Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add how to install from MS Store using PowerShell #2925

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 44 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,50 @@ If you are new to the Windows Package Manager, you might want to [Explore the Wi

### Microsoft Store [Recommended]

The client is distributed within the [App Installer](https://www.microsoft.com/p/app-installer/9nblggh4nns1) package.
The client is distributed within the [App Installer](https://www.microsoft.com/p/app-installer/9nblggh4nns1) package.

### Microsoft Store using PowerShell

```PowerShell
$applicationId = "9NBLGGH4NNS1" # Microsoft.DesktopAppInstaller_8wekyb3d8bbwe
$skuId = 0016
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why create a variable here when it's only used once later?


# Obtain packageFamilyName from applicationId
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to obtain the packageFamilyName if it is already known?

$webpage = Invoke-WebRequest -UseBasicParsing -Uri "https://bspmts.mp.microsoft.com/v1/public/catalog/Retail/Products/$applicationId/applockerdata"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if talking directly to this endpoint would be advertised by us.

Copy link
Author

@JuryA JuryA Feb 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not needed... We can hardcode packageFamilyName directly as:

$packageFamilyName = 'Microsoft.Microsoft.DesktopAppInstaller_8wekyb3d8bbwe'

It's constant for this product across all versions so it's safe and faster. This construct is part of the gist which I simply reused as is... It's definitely better not to depend on any APIs, let alone unofficial ones.

$packageFamilyName = ($webpage | ConvertFrom-JSON).packageFamilyName
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Invoke-RestMethod will automatically parse the JSON rather than requiring an explicit call to ConvertFrom-JSON


# Prepare CIM session object
$namespaceName = "root\cimv2\mdm\dmmap"
$session = New-CimSession
$omaUri = "./Vendor/MSFT/EnterpriseModernAppManagement/AppInstallation"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why create a variable here when it's only used once later?

$newInstance = New-Object Microsoft.Management.Infrastructure.CimInstance "MDM_EnterpriseModernAppManagement_AppInstallation01_01", $namespaceName
$property = [Microsoft.Management.Infrastructure.CimProperty]::Create("ParentID", $omaUri, "string", "Key")
$newInstance.CimInstanceProperties.Add($property)
$property = [Microsoft.Management.Infrastructure.CimProperty]::Create("InstanceID", $packageFamilyName, "String", "Key")
$newInstance.CimInstanceProperties.Add($property)

# Set CIM session parameters
$flags = 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why create a variable here when it's only used once later?

$paramValue = [Security.SecurityElement]::Escape($('<Application id="{0}" flags="{1}" skuid="{2}"/>' -f $applicationId, $flags, $skuId))
$params = New-Object Microsoft.Management.Infrastructure.CimMethodParametersCollection
$param = [Microsoft.Management.Infrastructure.CimMethodParameter]::Create("param", $paramValue, "String", "In")
$params.Add($param)

try {
# we create the MDM instance and trigger the StoreInstallMethod
$instance = $session.CreateInstance($namespaceName, $newInstance)
$result = $session.InvokeMethod($namespaceName, $instance, "StoreInstallMethod", $params)
}
catch [Exception] {
write-host $_ | out-string
}

# Dispose CIM session object
Remove-CimSession -CimSession $session

# Wait for a while - application is installed from Microsoft Store on the background
```
*Credit: [@JuryA](https://github.com/JuryA), inspired by [@adotcoop](https://gist.github.com/adotcoop) and his [Install-CompanyPortal.ps1](https://gist.github.com/adotcoop/0241d371684c3771000385dd93da77e4#file-install-companyportal-ps1)*

### Development Releases

Expand Down