Kết quả thực nghiệm
Tôi đã viết một số PowerShell rằng, khi chạy dưới dạng tập lệnh phát hiện, sẽ bỏ các biến môi trường mà tập lệnh phát hiện nhìn thấy vào tệp nhật ký. Kịch bản đó là ở cuối câu trả lời này.
Sau đó, tôi khiến tập lệnh này được chạy bởi máy khách SCCM bằng cách triển khai Loại triển khai với các tham số "Hành vi cài đặt" và "Yêu cầu đăng nhập" khác nhau. Các kết quả trong bảng dưới đây:
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
là tên người dùng
cnX
là tên máy tính
Phân tích
Các kết quả trên là đáng ngạc nhiên bởi vì bối cảnh mà tập lệnh phát hiện chạy dường như phụ thuộc một phần vào việc Ứng dụng được triển khai cho người dùng hay hệ thống. Điều này đủ gây ngạc nhiên khi tôi chạy thử nghiệm lần thứ hai. Kết quả phù hợp.
Chúng ta có thể rút ra các giả thuyết sau đây từ bảng trên:
- Khi một Ứng dụng được triển khai cho người dùng, tập lệnh phát hiện PowerShell cho Ứng dụng đó sẽ được chạy như người dùng đó.
- Khi một Ứng dụng được triển khai cho một hệ thống và Loại Triển khai được cài đặt cho hệ thống, tập lệnh phát hiện PowerShell cho Ứng dụng đó được chạy dưới dạng hệ thống.
- Khi một Ứng dụng được triển khai cho một hệ thống và Loại Triển khai được cài đặt cho người dùng, tập lệnh phát hiện PowerShell cho Ứng dụng đó được chạy dưới dạng người dùng đã đăng nhập.
Ba giả thuyết trên được hỗ trợ bởi các kết quả thử nghiệm. Cũng có thể có một số biến số khác chưa được kiểm tra trong đó các giả thuyết này không được giữ. Ít nhất, chúng là một tập hợp tốt các giả định ban đầu khi sử dụng các tập lệnh phát hiện PowerShell.
Bối cảnh không khớp (Cẩn thận!)
Jason Sandys đã ghi lại một thử nghiệm tương tự về các quy tắc cho bối cảnh cài đặt. Nếu bạn đọc bài đăng đó một cách cẩn thận, bạn có thể nhận thấy rằng các quy tắc cho bối cảnh cài đặt và bối cảnh tập lệnh phát hiện không hoàn toàn giống nhau. Dưới đây là các quy tắc vi phạm:
Khi hành vi cài đặt của Ứng dụng được đặt thành "Cài đặt là Hệ thống", trình cài đặt sẽ chạy dưới dạng hệ thống [bất kể triển khai cho người dùng].
Khi Ứng dụng được triển khai cho người dùng, tập lệnh phát hiện PowerShell cho Ứng dụng đó được chạy như người dùng đó [bất kể hành vi cài đặt có được đặt thành "Cài đặt dưới dạng hệ thống"].
Điều này có nghĩa là một Ứng dụng có hành vi cài đặt, Cài đặt như hệ thống , và được triển khai cho bộ sưu tập người dùng sẽ sử dụng bối cảnh hệ thống để cài đặt, nhưng bối cảnh người dùng để phát hiện.
Ai đó viết tập lệnh phát hiện cho Ứng dụng có hành vi cài đặt là "Cài đặt như hệ thống" nên cẩn thận để tránh phụ thuộc vào bất kỳ phần nào của môi trường thay đổi giữa bối cảnh hệ thống và người dùng. Mặt khác, việc phát hiện Ứng dụng được triển khai vào bộ sưu tập hệ thống có thể thành công trong khi phát hiện cùng một Ứng dụng được triển khai cho bộ sưu tập người dùng không thành công.
Kịch bản
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)
}