从Windows批处理文件调用PowerShell cmdlets

20

好的,有些简单的东西对我来说就是行不通。我有一个接受单个参数的cmdlet。我试图在Windows批处理文件中调用一个cmdlet。批处理文件包含:

cd %SystemRoot%\system32\WindowsPowerShell\v1.0
powershell Set-ExecutionPolicy Unrestricted
powershell 'C:\convert-utf8-to-utf16.ps1 C:\test.txt'
powershell Set-ExecutionPolicy Restricted
pause

我的ps1文件再次没有做任何特殊操作:

function convert-utf8-to-utf16 {   
  $tempfile = "C:\temp.txt"
  set-ExecutionPolicy Unrestricted
  get-content -Path $args[0] -encoding utf8 | out-file $tempfile -encoding Unicode
  set-ExecutionPolicy Restricted
}
当我执行批处理文件时,它只是运行到完成(没有错误消息),并且似乎没有创建temp.txt文件。 我可以在PS命令提示符下运行PowerShell命令文件,但在cmd中不能运行! 有人有任何想法可能出了什么问题吗?

Johannes:cmd.exe是一个Win32应用程序(尽管许多人仍然认为它是DOS command.com)。[问题应该被编辑] - user1686
有没有关于此的完整源代码的最终解决方案? - Kiquenet
6个回答

22

从 Powershell 版本 2 开始,您可以像这样运行 Powershell 脚本...

powershell -ExecutionPolicy RemoteSigned -File "C:\Path\Script.ps1" "Parameter with spaces" Parameter2

现在,如果我能找到一种处理将文件拖放到Powershell脚本的方法就好了。


非常感谢,这解决了我的头疼问题,并避免了将PowerShell转换为NSIS的麻烦。 - CharlesB

8
我会为您翻译以下内容:

我在我的博客文章这里中解释了为什么您希望从批处理文件中调用PowerShell脚本以及如何执行。

基本上,这就是您要寻找的内容:

PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& 'C:\convert-utf8-to-utf16.ps1' 'C:\test.txt'"

如果您需要以管理员身份运行PowerShell脚本,请使用以下命令:

PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& {Start-Process PowerShell -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File ""C:\convert-utf8-to-utf16.ps1"" ""C:\test.txt""' -Verb RunAs}"

不要像硬编码整个PowerShell脚本路径那样,建议按照我的博客文章所述的方式将批处理文件和PowerShell脚本文件放在同一目录中。


5
问题出在 ps1 文件中——你声明了一个函数,但没有调用它。 我会将其修改为这样:
param($path)
function convert-utf8-to-utf16 {   
 $tempfile = "C:\temp.txt"
 set-ExecutionPolicy Unrestricted
 get-content -Path $args[0] -encoding utf8 | out-file $tempfile -encoding Unicode
 set-ExecutionPolicy Restricted
}

convert-utf8-to-utf16 $path

这将起作用。但是这并不是必需的,你可以简单地省略函数声明并将函数体移动到脚本中:

param($path)
$tempfile = "C:\temp.txt"
set-ExecutionPolicy Unrestricted
get-content -Path $path -encoding utf8 | out-file $tempfile -encoding Unicode
set-ExecutionPolicy Restricted

3
# Test-Args.ps1
param($first, $second)
write-host $first
write-host $second

从命令提示符中调用:

PowerShell.exe -NoProfile -Command "& {./Test-Args.ps1 'C:\Folder A\One' 'C:\Folder B\Two'}"

令人困惑的是,如果脚本所在的文件夹路径包含空格,PowerShell 在引号中无法识别脚本名称:

PowerShell.exe -NoProfile -Command "& {'C:\Folder X\Test-Args.ps1' 'C:\Folder
 A\One' 'C:\Folder B\Two'}"

但是你可以通过使用类似以下的方法来解决这个问题:
PowerShell.exe -NoProfile -Command "& {set-location 'C:\Folder X';./Test-Args.ps1 'C:\Folder
 A\One' 'C:\Folder B\Two'}"

不要在你的.PS1文件名中使用空格,否则你就没戏了。


1

我已经解决了这个问题... ps1文件不需要被包装成一个函数。只需要这个声明就可以了。

$tempfile = "C:\temp.txt"  
get-content -Path $args[0] -encoding utf8 | out-file $tempfile -encoding unicode      

而批处理文件则像这样调用它:

cd %SystemRoot%\system32\WindowsPowerShell\v1.0
powershell Set-ExecutionPolicy Unrestricted
powershell "& 'C:\convert-utf8-to-utf16.ps1 C:\test.txt' 'C:\test.txt'"
powershell Set-ExecutionPolicy Restricted
pause

你遇到的问题是脚本定义了一个函数,但没有执行它。你可以在脚本末尾调用该函数,或者根本不将代码包装在函数中(就像你最终所做的那样)。 - JasonMArcher

0
尝试使用这个语法:
cd %SystemRoot%\system32\WindowsPowerShell\v1.0
powershell {Set-ExecutionPolicy Unrestricted}
powershell "& C:\convert-utf8-to-utf16.ps1 C:\test.txt"
powershell {Set-ExecutionPolicy Restricted}
pause

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接