Hasil empiris
Saya menulis beberapa PowerShell bahwa, ketika dijalankan sebagai skrip deteksi, membuang variabel lingkungan yang skrip deteksi lihat ke file log. Naskah itu ada di akhir jawaban ini.
Saya kemudian menyebabkan skrip ini dijalankan oleh klien SCCM dengan menyebarkan Jenis Penempatan dengan parameter "Perilaku Instalasi" dan "Persyaratan masuk" yang berbeda. Hasilnya ada dalam tabel di bawah ini:
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
adalah nama pengguna
cnX
adalah nama komputer
Analisis
Hasil di atas mengejutkan karena konteks yang menjalankan skrip deteksi tampaknya sebagian bergantung pada apakah Aplikasi itu digunakan untuk pengguna atau sistem. Ini cukup mengejutkan bahwa saya menjalankan tes untuk kedua kalinya. Hasilnya konsisten.
Kita dapat dengan tentangan menarik hipotesis berikut dari tabel di atas:
- Ketika Aplikasi dikerahkan ke pengguna, skrip deteksi PowerShell untuk Aplikasi itu dijalankan sebagai pengguna itu.
- Ketika Aplikasi dikerahkan ke sistem dan Tipe Penempatan diinstal untuk sistem, skrip deteksi PowerShell untuk Aplikasi itu dijalankan sebagai sistem.
- Ketika Aplikasi dikerahkan ke sistem dan Jenis Penerapan diinstal untuk pengguna, skrip deteksi PowerShell untuk Aplikasi tersebut dijalankan sebagai pengguna yang masuk.
Tiga hipotesis di atas didukung oleh hasil tes. Mungkin ada beberapa variabel lain yang tidak diuji di mana hipotesis ini tidak berlaku. Setidaknya, itu adalah seperangkat asumsi awal yang baik ketika menggunakan skrip deteksi PowerShell.
Konteks yang Tidak Sesuai (Waspadalah!)
Jason Sandys mendokumentasikan tes serupa dari aturan untuk konteks instalasi. Jika Anda membaca posting itu dengan seksama, Anda mungkin memperhatikan bahwa aturan untuk konteks pemasangan dan konteks skrip deteksi tidak sama. Berikut adalah aturan yang melanggar:
Ketika perilaku instalasi Aplikasi diatur ke "Instal sebagai Sistem", installer dijalankan sebagai sistem [terlepas dari penyebaran kepada pengguna].
Ketika Aplikasi dikerahkan ke pengguna, skrip deteksi PowerShell untuk Aplikasi itu dijalankan sebagai pengguna itu [terlepas dari apakah perilaku instalasi diatur ke "Instal sebagai Sistem"].
Ini berarti bahwa Aplikasi yang memiliki perilaku instalasi "Instal sebagai sistem" dan digunakan untuk koleksi pengguna akan menggunakan konteks sistem untuk instalasi, tetapi konteks pengguna untuk deteksi.
Seseorang yang menulis skrip deteksi untuk Aplikasi di mana perilaku instalasi adalah "Instal sebagai Sistem" harus berhati-hati untuk menghindari mengandalkan pada bagian mana pun dari lingkungan yang berubah antara sistem dan konteks pengguna. Jika tidak, deteksi Aplikasi yang digunakan untuk koleksi sistem mungkin berhasil sementara deteksi aplikasi yang sama persis yang digunakan untuk koleksi pengguna gagal.
Naskah
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)
}