用powershell调度任务
scheduling task with powershell
我正在尝试在远程计算机上安排任务,我成功地在远程计算机上安排了一个任务,但它没有执行。就像我想在某个触发时间下载文件一样。
在我的任务调度程序中,它显示任务已成功完成,但我没有看到任何文件已下载。
$ComputerName = "win12"
$cr=Get-Credential $ComputerName\administrator
$Session = New-PSSession -ComputerName $ComputerName -Credential $cr
Invoke-Command -Session $Session -ScriptBlock {
$start = (Get-Date).AddMinutes(1).ToString("HH:mm:ss")
[string]$Result = schtasks /create /tn "kk" /tr "powershell.exe (New-Object System.Net.WebClient).DownloadFile('http://server12/vdir/OracleXE.exe','C:\abc.exe')" /sc once /st $start /ru "administrator" /rp "passw0rd@12"
$Result += schtasks /run /tn "kk"
$Result
}
即使触发时间已过或我将任务强制到 运行,文件仍未下载。当我 运行 单独命令时,它可以很好地下载文件,但不能使用任务调度程序。
您似乎对 kerberos 双跳委派有疑问。我的建议:
- 创建一个 ps1 文件并安排脚本文件
- 在调用命令中设置并使用 CredSSP 进行身份验证
- 可能是计划作业比计划任务更适合这种情况。
问题在于 powershell 和 schtasks 如何处理引号。由于 /tr 命令需要用双引号括起来,因此在命令内部需要双引号的地方使用单引号。这些又被转换为双引号。这与 powershell.exe 不兼容,因为它反过来无法解释命令中的双引号。
到目前为止我发现的唯一解决方法是将命令转换为 Base64,这样可以保留命令的确切格式,然后使用 -encodedCommand 参数将其传递给 powershell.exe
$ComputerName = "win12"
$cr=Get-Credential $ComputerName\administrator
$Session = New-PSSession -ComputerName $ComputerName -Credential $cr
$command = "(New-Object System.Net.WebClient).DownloadFile('http://server12/vdir/OracleXE.exe','C:\abc.exe')"
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
$encodedCommand = [Convert]::ToBase64String($bytes)
Invoke-Command -Session $Session -ScriptBlock {
$start = (Get-Date).AddMinutes(1).ToString("HH:mm:ss")
[string]$Result = schtasks /create /tn "kk" /tr "powershell.exe -encodedCommand $encodedCommand" /sc once /st $start /ru "administrator" /rp "passw0rd@12"
$Result += schtasks /run /tn "kk"
$Result
}
更新:
另一种可能不那么复杂但需要 PowerShell 3.0 的方法是使用计划作业。
$ComputerName = "win12"
$cr=Get-Credential $ComputerName\administrator
$Session = New-PSSession -ComputerName $ComputerName -Credential $cr
$command = {(New-Object System.Net.WebClient).DownloadFile(
'http://server12/vdir/OracleXE.exe','C:\abc.exe')}
Invoke-Command -Session $Session -ScriptBlock {
Register-ScheduledJob -Name kk -ScriptBlock $command;
(get-scheduledjob kk).Run() }
}
我正在尝试在远程计算机上安排任务,我成功地在远程计算机上安排了一个任务,但它没有执行。就像我想在某个触发时间下载文件一样。 在我的任务调度程序中,它显示任务已成功完成,但我没有看到任何文件已下载。
$ComputerName = "win12"
$cr=Get-Credential $ComputerName\administrator
$Session = New-PSSession -ComputerName $ComputerName -Credential $cr
Invoke-Command -Session $Session -ScriptBlock {
$start = (Get-Date).AddMinutes(1).ToString("HH:mm:ss")
[string]$Result = schtasks /create /tn "kk" /tr "powershell.exe (New-Object System.Net.WebClient).DownloadFile('http://server12/vdir/OracleXE.exe','C:\abc.exe')" /sc once /st $start /ru "administrator" /rp "passw0rd@12"
$Result += schtasks /run /tn "kk"
$Result
}
即使触发时间已过或我将任务强制到 运行,文件仍未下载。当我 运行 单独命令时,它可以很好地下载文件,但不能使用任务调度程序。
您似乎对 kerberos 双跳委派有疑问。我的建议:
- 创建一个 ps1 文件并安排脚本文件
- 在调用命令中设置并使用 CredSSP 进行身份验证
- 可能是计划作业比计划任务更适合这种情况。
问题在于 powershell 和 schtasks 如何处理引号。由于 /tr 命令需要用双引号括起来,因此在命令内部需要双引号的地方使用单引号。这些又被转换为双引号。这与 powershell.exe 不兼容,因为它反过来无法解释命令中的双引号。
到目前为止我发现的唯一解决方法是将命令转换为 Base64,这样可以保留命令的确切格式,然后使用 -encodedCommand 参数将其传递给 powershell.exe
$ComputerName = "win12"
$cr=Get-Credential $ComputerName\administrator
$Session = New-PSSession -ComputerName $ComputerName -Credential $cr
$command = "(New-Object System.Net.WebClient).DownloadFile('http://server12/vdir/OracleXE.exe','C:\abc.exe')"
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
$encodedCommand = [Convert]::ToBase64String($bytes)
Invoke-Command -Session $Session -ScriptBlock {
$start = (Get-Date).AddMinutes(1).ToString("HH:mm:ss")
[string]$Result = schtasks /create /tn "kk" /tr "powershell.exe -encodedCommand $encodedCommand" /sc once /st $start /ru "administrator" /rp "passw0rd@12"
$Result += schtasks /run /tn "kk"
$Result
}
更新:
另一种可能不那么复杂但需要 PowerShell 3.0 的方法是使用计划作业。
$ComputerName = "win12"
$cr=Get-Credential $ComputerName\administrator
$Session = New-PSSession -ComputerName $ComputerName -Credential $cr
$command = {(New-Object System.Net.WebClient).DownloadFile(
'http://server12/vdir/OracleXE.exe','C:\abc.exe')}
Invoke-Command -Session $Session -ScriptBlock {
Register-ScheduledJob -Name kk -ScriptBlock $command;
(get-scheduledjob kk).Run() }
}