[英]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.