[英]How to run my PowerShell module cmdlet as SYSTEM?
創建了一個 PowerShell 模塊,它有一個 function 並為該 function 公開了一個 cmdlet。內置的 PowerShell 5.1 和 pwsh.exe 7.3.1(使用 MSI 安裝程序安裝)可以毫無問題地檢測和運行該 cmdlet。
現在我需要該 cmdlet 在 Windows 任務計划程序中“無論用戶是否登錄都運行” 。
當我嘗試以NT AUTHORITY\SYSTEM
身份運行我的 PowerShell 模塊的 cmdlet 時,問題就出現了。
我需要這樣做,因為在任務計划程序中, 這似乎是獲得計划任務“無論用戶是否登錄都運行”的唯一方法。 (我不想手動輸入任何 Windows 用戶帳戶的用戶名或密碼)
理想情況下,我寧願使用內置的管理員安全組,但如您所見,如果用戶未登錄,我將無法運行該任務。
所以我真的被困在這里不知道該怎么辦。 我認為這是我遇到的邊緣情況之一。
我需要找到一種方法,以便當 PowerShell 作為 SYSTEM 運行時,它仍然能夠檢測到我的模塊的 cmdlet。
我知道當 PowerShell 作為 SYSTEM 運行時未檢測到我的 cmdlet,因為我使用PsExec64對其進行了測試。
我把我的 PowerShell 模塊放在這里(這是他們從在線畫廊默認安裝的地方):
C:\Users\<UserName>\OneDrive\Documents\PowerShell\Modules\ModuleFolder
這是我用來創建任務的 PowerShell 腳本的整個塊。
$action = New-ScheduledTaskAction -Execute "pwsh.exe" -Argument "-command 'myCmdLet -parameter1 $variable1"
# First thing I tried
$TaskPrincipal = New-ScheduledTaskPrincipal -GroupId "BUILTIN\Administrators" -RunLevel Highest
# Second thing I tried
$TaskPrincipal = New-ScheduledTaskPrincipal -UserID "NT AUTHORITY\SYSTEM" -LogonType ServiceAccount -RunLevel Highest
$trigger = New-ScheduledTaskTrigger -AtStartup
Register-ScheduledTask -Action $action -Trigger $trigger -Principal $TaskPrincipal -TaskName "Name" -Description "Description"
$TaskSettings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -Compatibility Win8 -StartWhenAvailable
Set-ScheduledTask -TaskName "Name" -Settings $TaskSettings
更新:
我找到了一種方法:
$TaskPrincipal = New-ScheduledTaskPrincipal -LogonType S4U -UserId $env:USERNAME -RunLevel Highest
它以管理員身份運行任務(因為模塊 cmdlet 甚至在沒有管理員權限的情況下都無法工作)並且還檢查了我真正想做的這 2 個框。 但是,仍在尋找一種方法,使我的模塊的 cmdlet 在以 SYSTEM 身份運行時為 PowerShell 所知,它將提供 1 個好處,AFAIK,即消除對計算機上現有的特定用戶帳戶的依賴。
總結一下:
您的問題是您希望計划任務使用的模塊安裝在當前用戶的 scope 中,而以不同用戶身份運行的任務(例如NT AUTORITY\SYSTEM
)將看不到。
簡單的解決方案是通過傳遞給Install-Module
的-Scope AllUsers
參數為所有用戶安裝模塊(需要提升)。
但是,即使不可能或不需要,也有一個解決方案,即將完整的模塊路徑傳遞給在任務上下文中執行的顯式Import-Module
調用,如下所示。
由於您的任務需要以提升的方式運行,就像您 state 一樣,只有當該用戶是管理員時,才能在當前用戶的上下文中運行; 如您所見,您可以按如下方式進行設置(需要提升):
$taskPrincipal = New-ScheduledTaskPrincipal -LogonType S4U -UserId $env:USERNAME -RunLevel Highest
以用戶NT AUTORITY\SYSTEM
身份運行任務總是會運行:
-LogonType Service
。C:\Windows\System32
<hostname>$
反映在$env:USERNAME
中,其中<hostname>
是本地計算機的名稱,以及C:\Windows\system32\config\systemprofile
的$HOME
/ $env:USERPROFILE
文件夾。以下自包含示例:
NT AUTHORITY\SYSTEM
運行~/_test.psm1
和~/_test.txt
,臨時任務名為_Test
)#requires -RunAsAdministrator
$ErrorActionPreference = 'Stop'
try {
# Create a simple script module that exports function Get-Foo,
# in the current user's home dir., named '_test.psm1'
@'
function Get-Foo { "Hi, I'm running at $(Get-Date)`n * as $env:USERNAME (whose home dir. is '$HOME')`n * in '$PWD'`n * $(('NON-elevated', 'ELEVATED')[[bool] (net session 2>$null)])." }
'@ > ~/_test.psm1
# Set up the scheduled task:
# The command (program) to run.
# Import the test-module via its full path, call Get-Foo, and redirect all output streams
# to file '_test.txt' in the current users' home dir.
$action = New-ScheduledTaskAction -Execute powershell -Argument "-ExecutionPolicy Bypass -NoProfile -Command & { Import-Module `"$((Get-Item ~/_test.psm1).FullName)`"; Get-Foo } *> `"$((Get-Item ~).FullName)\_test.txt`""
# Run as 'NT AUTHORITY\SYSTEM', which runs:
# * invisibly
# * whether or not someone is logged on
# * implicitly with elevation
$user = New-ScheduledTaskPrincipal -UserID 'NT AUTHORITY\SYSTEM' -LogonType ServiceAccount
# # Advanced settings such as whether to allow start on demand, not running when on batter power, ...
# $settings = New-ScheduledTaskSettingsSet
# When to run it: Run a few seconds from now, once.
$secsFromNow = 5
$when = (Get-Date).AddSeconds($secsFromNow)
$trigger = New-ScheduledTaskTrigger -Once -At $when
# Create the task from the above.
$newTask = New-ScheduledTask -Action $action -Principal $user -Trigger $trigger
# Register the task with name '_Test'
Write-Verbose -Verbose "Creating task..."
Register-ScheduledTask '_Test' -InputObject $newTask -Force
Write-Verbose -Verbose "Task will execute invisibly in $secsFromNow seconds, running as 'NT AUTHORITY\SYSTEM'. Waiting (plus a few extra seconds)..."
Start-Sleep ($secsFromNow + 5) # Wait an extra few seconds to give the task time to complete.
Write-Verbose -Verbose "Task is assumed to have run. Output logged:"
Get-Content ~/_test.txt
}
finally {
# Clean up.
Remove-Item -ErrorAction Ignore ~/_test.psm1, ~/_test.txt
Unregister-ScheduledTask -ErrorAction Ignore -TaskName _Test -Confirm:$false
}
樣本 output:
VERBOSE: Creating task...
TaskPath TaskName State
-------- -------- -----
\ _Test Ready
VERBOSE: Task will execute invisibly in 5 seconds, running as 'NT AUTHORITY\SYSTEM'. Waiting (plus a few extra seconds)...
VERBOSE: Task is assumed to have run. Output logged:
Hi, I'm running at 01/11/2023 17:06:04
* as WORKSTATION1$ (whose home dir. is 'C:\Windows\system32\config\systemprofile')
* in 'C:\Windows\system32'
* ELEVATED.
最后 4 行是模塊函數的 ( Get-Foo
的) output,證明模塊已成功導入到任務上下文中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.