Resultados empíricos
Eu escrevi um PowerShell que, quando executado como um script de detecção, despeja as variáveis de ambiente que o script de detecção vê em um arquivo de log. Esse script está no final desta resposta.
Em seguida, faço com que esse script seja executado pelo cliente SCCM implantando um tipo de implantação com diferentes parâmetros "Comportamento de instalação" e "Requisito de logon". Os resultados estão na tabela abaixo:
Test InstallationBehavior LogonRequirement DeployedTo LoggedOnUser ScriptRunAs
---- -------------------- ---------------- ---------- ------------ -----------
1.1a Install for user Only when a user is logged on un2 un2 un2
1.1b Install for user Only when a user is logged on cn1 un2 un2
1.1c Install for user Only when a user is logged on cn1 un1 un1
1.2a Install for system Only when a user is logged on un2 un2 un2
1.2b Install for system Only when a user is logged on cn1 un2 cn1
1.2c Install for system Only when a user is logged on cn1 un1 cn1
1.3a Install for system Whether or not a user is logged on un2 un2 un2
1.3b Install for system Whether or not a user is logged on cn1 un2 cn1
1.3c Install for system Whether or not a user is logged on cn1 un1 cn1
-
unX
são nomes de usuário -
cnX
são nomes de computadores
Análise
Os resultados acima são surpreendentes porque o contexto em que um script de detecção é executado parece depender, em parte, do fato de o Aplicativo ter sido implementado em um usuário ou em um sistema. Isso foi o suficiente para uma surpresa que eu fiz os testes uma segunda vez. Os resultados foram consistentes.
Podemos desenhar as seguintes hipóteses da tabela acima:
- Quando um aplicativo é implantado em um usuário, um script de detecção do PowerShell para esse aplicativo é executado como esse usuário.
- Quando um aplicativo é implantado em um sistema e o tipo de implantação é instalado no sistema, um script de detecção do PowerShell para esse aplicativo é executado como o sistema.
- Quando um aplicativo é implantado em um sistema e o tipo de implantação é instalado para o usuário, um script de detecção do PowerShell para esse aplicativo é executado como o usuário conectado.
As três hipóteses acima são suportadas pelos resultados do teste. Pode haver outras variáveis que não foram testadas onde essas hipóteses não se sustentam. Eles são, pelo menos, um bom conjunto de suposições iniciais ao usar scripts de detecção do PowerShell.
Contextos Incompatíveis (Cuidado!)
Jason Sandys documentou um teste semelhante das regras para o contexto de instalação. Se você leia atentamente essa postagem, você pode notar que as regras para contexto de instalação e contexto de script de detecção não são exatamente as mesmas. Aqui estão as regras ofensivas:
When an Application's installation behavior is set to "Install as System" the installer is run as system [regardless of deployment to user].
When an Application is deployed to a user, a PowerShell detection script for that Application is run as that user [regardless of whether installation behavior is set to "Install as System"].
Isso significa que um Aplicativo que tenha o comportamento de instalação “Instalar como sistema” e implantado em uma coleção de usuários usará o contexto do sistema para instalação, mas o contexto do usuário para detecção. / strong>
Alguém que está escrevendo scripts de detecção para Aplicativos em que o comportamento da instalação é "Instalar como Sistema" deve ter cuidado para evitar confiar em qualquer parte do ambiente que muda entre o sistema e os contextos do usuário. Caso contrário, a detecção de um Aplicativo implantado em uma coleção de sistemas pode ser bem-sucedida enquanto a detecção do mesmo Aplicativo implantado em uma coleção de usuários falha.
Script
function Write-EnvToLog
{
$appName = 'script-detect-test'
$logFolderPath = "c:\$appName-$([System.Environment]::UserName)"
if ( -not (Test-Path $logFolderPath -PathType Container) )
{
New-Item -Path $logFolderPath -ItemType Directory | Out-Null
}
if ( -not (Test-Path $logFolderPath -PathType Container ) )
{
return
}
$logFileName = "$appName'__$((Get-Date).ToString("yyyy-MM-dd__HH-mm-ss")).txt"
$fp = "$logFolderPath\$logFileName"
Get-ChildItem Env: | Out-File $fp | Out-Null
return $true
}
try
{
if ( Write-EnvToLog ) { "Detected!" }
[System.Environment]::Exit(0)
}
catch
{
[System.Environment]::Exit(0)
}