Resultados empíricos
Eu escrevi alguns PowerShell que, quando executados como um script de detecção, despejam 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 da 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 computador
Análise
Os resultados acima são surpreendentes porque o contexto em que um script de detecção é executado parece depender, em parte, se o Aplicativo foi implantado em um usuário ou sistema. Isso foi uma surpresa o suficiente para eu executar os testes pela segunda vez. Os resultados foram consistentes.
Podemos traçar provisoriamente 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 para o 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ê ler essa publicação com atenção, poderá observar que as regras para o contexto de instalação e o contexto do script de detecção não são as mesmas. Aqui estão as regras incorretas:
Quando o comportamento de instalação de um aplicativo é definido como "Instalar como sistema", o instalador é executado como sistema [independentemente da implantação no usuário].
Quando um Aplicativo é implantado em um usuário, um script de detecção do PowerShell para esse Aplicativo é executado como esse usuário [independentemente de o comportamento da instalação estar definido como "Instalar como Sistema"].
Isso significa que um Aplicativo que possui o comportamento de instalação "Instalar como sistema" e é implantado em uma coleção de usuários utilizará o contexto do sistema para instalação, mas o contexto do usuário para detecção.
Alguém escrevendo scripts de detecção para Aplicativos em que o comportamento da instalação é "Instalar como Sistema" deve ter cuidado para evitar depender de qualquer parte do ambiente que seja alterada entre os contextos do sistema e do usuário. Caso contrário, a detecção de um Aplicativo implantado em uma coleção de sistemas pode ter êxito, enquanto a detecção do mesmo Aplicativo implantado em uma coleção de usuários falha.
Roteiro
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)
}