You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python调用多行PowerShell单命令报错,求无需.ps1文件的执行方案

解决Python调用PowerShell创建定时任务的引号解析错误

问题重现

尝试在Python中直接执行PowerShell脚本创建定时任务,避免生成.ps1文件,当前代码如下:

import os

command='''$jobname = "Recurring PowerShell Task"
$script =  "w32tm /resync"
$action = New-ScheduledTaskAction –Execute "$pshome\powershell.exe" -Argument  "$script"
$duration = ([timeSpan]::maxvalue)
$repeat = (New-TimeSpan -hours 3)
$trigger =New-ScheduledTaskTrigger -Once -At (Get-Date).Date -RepetitionInterval $repeat -RepetitionDuration $duration


$msg = "Enter the username and password that will run the task"; 
$credential = $Host.UI.PromptForCredential("Task username and password",$msg,"$env:userdomain\$env:username",$env:userdomain)
$username = $credential.UserName
$password = $credential.GetNetworkCredential().Password
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -RunOnlyIfNetworkAvailable -DontStopOnIdleEnd
 Register-ScheduledTask -TaskName $jobname -Action $action -Trigger $trigger -RunLevel Highest -User $username -Password $password -Settings $settings'''

os.system("powershell "+command)

运行后出现错误:

+ $jobname = Recurring PowerShell Task
+            ~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Recurring:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

错误原因

  1. 引号丢失:通过os.system传递命令时,cmd.exe会解析外层引号,导致PowerShell脚本中的字符串引号被剥离,PowerShell将Recurring识别为命令而非字符串的一部分,引发找不到命令的错误。
  2. 符号错误:New-ScheduledTaskAction后的–Execute使用了中文破折号,PowerShell无法识别该符号,会导致参数解析失败。

解决建议

1. 修正符号错误

将脚本中所有中文破折号–替换为英文短横线-,例如:

$action = New-ScheduledTaskAction -Execute "$pshome\powershell.exe" -Argument  "$script"

2. 正确处理引号传递

使用PowerShell的-Command参数包裹整个脚本,并在Python中对引号进行转义,避免被cmd.exe解析丢失。修改os.system调用为:

os.system('powershell -Command "{0}"'.format(command.replace('"', '\\"')))

3. 推荐使用subprocess模块替代os.system

subprocess模块对命令参数的处理更可靠,避免多层解析问题,示例代码:

import subprocess

command='''$jobname = "Recurring PowerShell Task"
$script =  "w32tm /resync"
$action = New-ScheduledTaskAction -Execute "$pshome\powershell.exe" -Argument  "$script"
$duration = ([timeSpan]::maxvalue)
$repeat = (New-TimeSpan -hours 3)
$trigger =New-ScheduledTaskTrigger -Once -At (Get-Date).Date -RepetitionInterval $repeat -RepetitionDuration $duration


$msg = "Enter the username and password that will run the task"; 
$credential = $Host.UI.PromptForCredential("Task username and password",$msg,"$env:userdomain\$env:username",$env:userdomain)
$username = $credential.UserName
$password = $credential.GetNetworkCredential().Password
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -RunOnlyIfNetworkAvailable -DontStopOnIdleEnd
Register-ScheduledTask -TaskName $jobname -Action $action -Trigger $trigger -RunLevel Highest -User $username -Password $password -Settings $settings'''

subprocess.run(["powershell", "-Command", command], shell=True)

4. 可选:使用Base64编码传递脚本

如果引号转义仍然有问题,可以将PowerShell脚本编码为Base64,通过-EncodedCommand参数执行,彻底避免引号解析问题:

import subprocess
import base64

command='''$jobname = "Recurring PowerShell Task"
$script =  "w32tm /resync"
$action = New-ScheduledTaskAction -Execute "$pshome\powershell.exe" -Argument  "$script"
$duration = ([timeSpan]::maxvalue)
$repeat = (New-TimeSpan -hours 3)
$trigger =New-ScheduledTaskTrigger -Once -At (Get-Date).Date -RepetitionInterval $repeat -RepetitionDuration $duration


$msg = "Enter the username and password that will run the task"; 
$credential = $Host.UI.PromptForCredential("Task username and password",$msg,"$env:userdomain\$env:username",$env:userdomain)
$username = $credential.UserName
$password = $credential.GetNetworkCredential().Password
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -RunOnlyIfNetworkAvailable -DontStopOnIdleEnd
Register-ScheduledTask -TaskName $jobname -Action $action -Trigger $trigger -RunLevel Highest -User $username -Password $password -Settings $settings'''

# 按PowerShell要求的UTF-16LE编码后转Base64
encoded_command = base64.b64encode(command.encode('utf-16le')).decode('utf-8')
subprocess.run(["powershell", "-EncodedCommand", encoded_command])

内容的提问来源于stack exchange,提问作者ripdechains

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 03:30:55