Currently Intune scripts run in Windows PowerShell.
However, if we want to use some pwsh-only modules (e.g. winget.client) in those scripts, we need to launch pwsh, wait for completion, capture the output (json), and pass it on to Intune. This should work both in system and user context.
We want to run this on thousands of PCs, so I suspect there will be a bunch of corner cases (where this may fail) that are difficult to predict. Has anyone already tackled this and is willing to share the experience?
To start from somewhere, we drafted a quick snippet to use at the top of the Intune script:
if ($PSVersionTable.PSEdition -ne "Core") {
#This only covers the pwsh deployed with the Appx/Store
$ResolvePwshPath =
if ([System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value -eq "S-1-5-18") {
# running as system
Resolve-Path "${env:ProgramFiles}\WindowsApps\Microsoft.PowerShell_*_*__8wekyb3d8bbwe" |
Sort-Object { [version]($_.Path -replace '^[^\d]+_((\d+\.)*\d+)_.*', '$1') } |
Select-Object -ExpandProperty Path
} else {
# running as user
Get-Command -Name pwsh.exe -CommandType Application |
Sort-Object -Property Version -Descending |
Select-Object -First 1 -ExpandProperty Source
}
if ($ResolvePwshPath) {
$argList = @("-NoProfile","-ExecutionPolicy Bypass","-MTA","-File",$MyInvocation.MyCommand.Path)
$procArg = @{
FilePath = $ResolvePwshPath
Wait = $true
PassThru = $true
ArgumentList = $argList
}
$proc = Start-Process @procArg
#TODO: need to capture output as well and pass it on
Exit $proc.ExitCode
} else {
throw "Powershell Core not found"
}
}