Empirische Ergebnisse
Ich habe eine PowerShell geschrieben, die beim Ausführen als Erkennungsskript die Umgebungsvariablen, die das Erkennungsskript sieht, in einer Protokolldatei speichert. Dieses Skript steht am Ende dieser Antwort.
Ich lasse dieses Skript dann vom SCCM-Client ausführen, indem ich einen Bereitstellungstyp mit unterschiedlichen Parametern "Installationsverhalten" und "Anmeldeanforderung" bereitstelle. Die Ergebnisse sind in der folgenden Tabelle aufgeführt:
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
sind Benutzernamen
cnX
sind Computernamen
Analyse
Die obigen Ergebnisse sind überraschend, da der Kontext, in dem ein Erkennungsskript ausgeführt wird, teilweise davon abzuhängen scheint, ob die Anwendung für einen Benutzer oder ein System bereitgestellt wurde. Dies war eine Überraschung genug, dass ich die Tests ein zweites Mal durchführte. Die Ergebnisse waren konsistent.
Wir können vorläufig die folgenden Hypothesen aus der obigen Tabelle ziehen:
- Wenn eine Anwendung für einen Benutzer bereitgestellt wird, wird ein PowerShell-Erkennungsskript für diese Anwendung als dieser Benutzer ausgeführt.
- Wenn eine Anwendung auf einem System bereitgestellt und der Bereitstellungstyp für das System installiert wird, wird ein PowerShell-Erkennungsskript für diese Anwendung als System ausgeführt.
- Wenn eine Anwendung auf einem System bereitgestellt und der Bereitstellungstyp für den Benutzer installiert wird, wird ein PowerShell-Erkennungsskript für diese Anwendung als angemeldeter Benutzer ausgeführt.
Die obigen drei Hypothesen werden durch die Testergebnisse gestützt. Möglicherweise gibt es einige andere Variablen, die nicht getestet wurden, wenn diese Hypothesen nicht zutreffen. Dies sind zumindest gute Voraussetzungen für die Verwendung von PowerShell-Erkennungsskripten.
Nicht übereinstimmende Kontexte (Vorsicht!)
Jason Sandys dokumentierte einen ähnlichen Test der Regeln für den Installationskontext. Wenn Sie diesen Beitrag sorgfältig lesen, werden Sie möglicherweise feststellen, dass die Regeln für den Installationskontext und den Erkennungsskriptkontext nicht ganz identisch sind. Hier sind die beleidigenden Regeln:
Wenn das Installationsverhalten einer Anwendung auf "Als System installieren" eingestellt ist, wird das Installationsprogramm als System ausgeführt [unabhängig von der Bereitstellung für den Benutzer].
Wenn eine Anwendung für einen Benutzer bereitgestellt wird, wird ein PowerShell-Erkennungsskript für diese Anwendung als dieser Benutzer ausgeführt [unabhängig davon, ob das Installationsverhalten auf "Als System installieren" festgelegt ist].
Dies bedeutet, dass eine Anwendung mit dem Installationsverhalten "Als System installieren" und in einer Benutzersammlung bereitgestellt wird, den Systemkontext für die Installation verwendet, den Benutzerkontext jedoch zur Erkennung.
Jemand, der Erkennungsskripte für Anwendungen schreibt, bei denen das Installationsverhalten "Als System installieren" lautet, sollte darauf achten, dass er sich nicht auf Teile der Umgebung verlässt, die sich zwischen dem System- und dem Benutzerkontext ändern. Andernfalls kann die Erkennung einer für eine Systemsammlung bereitgestellten Anwendung erfolgreich sein, während die Erkennung genau derselben für eine Benutzersammlung bereitgestellten Anwendung fehlschlägt.
Skript
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)
}