使用 Powershell 运行 Psexec 命令

9

这是我的第一篇帖子,请不要伤害我。我已经搜索了很多,但似乎找不到我想要的方法。我制作了一个脚本,将我的文件夹复制到\$computer\c$的多台计算机中。这些文件夹中有一个批处理文件,运行一个.exe文件。我想做的是让Powershell从我用于复制文件夹的相同computers.txt中提取数据,然后使用psexec运行批处理文件。我可以手动完成所有操作,但是脚本似乎存在问题,以下是我认为会起作用的代码,但实际上并没有。

    $computers = gc "C:\scripts\computers.txt"

foreach ($computer in $computers) {
if (test-Connection -Cn $computer -quiet) {
    cd C:\pstools
    psexec \\%computer cmd
    C:\Folder\install.bat"
} else {
    "$computer is not online"
}

}


这是实际的脚本复制和粘贴吗?还是重新输入的,可能有一些打字错误? - TheMadTechnician
我复制/粘贴了它。我在Powershell脚本编写方面非常新手,如果语法很糟糕,请见谅。 - noz3r0
尽量不要在PowerShell中使用psexec,我在这方面遇到了很多问题... - Root Loop
4个回答

12

好的,那么让我们从头开始吧。

$computers = gc "C:\scripts\computers.txt"

这将把"computers.txt"文件的内容加载到变量$computers中。很简单,没有任何问题。

接下来是一个ForEach循环。它将$computers的内容拆分,并将每一行(可能是计算机的名称)作为$computer处理,并针对花括号内的所有代码进行处理。

foreach ($computer in $computers) {

这个循环从一个标准的If-Then语句开始。(condition)如果为真,就执行{do stuff}。在这种情况下,它正在测试$computer是否在网络上可用。如果是,则尝试在其上运行PSExec。如果没有联机,则运行Else子句,我们稍后再说。

if (test-Connection -Cn $computer -quiet) {

然后它改变了目录。有点毫无意义,但好吧,随便你。你本可以像这样显式地调用它:C:\PSTools\PSExec.exe <arguments>并节省一行代码,但其实没有什么危害。

cd C:\pstools

那么您正在调用PSExec,但这里有一个小语法错误。它应该是$computer而不是%computer。此外,它应该只有您要执行的命令,而不是在第二行上使用cmd和命令。如果您使用调用运算符(&),使PowerShell意识到它正在尝试执行某些内容而不是运行命令或函数等,则可能会获得更好的结果。

& psexec \\$computer C:\Folder\install.bat

接下来是Else子句,如果计算机不在线,则写入字符串“$ computer is not online”,后跟Else子句和ForEach循环的闭合括号。

} else {
    "$computer is not online"
}


}

编辑:好的,你完成的脚本应该长这样(将目标路径用引号括起来以防路径里有空格):

$computers = gc "C:\scripts\computers.txt"

foreach ($computer in $computers) {
    if (test-Connection -Cn $computer -quiet) {
        & C:\pstools\psexec.exe \\$computer "C:\folder\install.bat"
    } else {
        "$computer is not online"
    }
}

好的,我明白如何将其缩小一点。感谢您提供了完整的细节。我的问题现在是我无法正确地使用Psexec函数,我不确定我做错了什么。如果我手动执行此操作,我会打开命令提示符并键入“psexec \hostname cmd”,然后我将进入该计算机的命令提示符,从那里我只需导航到所需文件夹并运行批处理文件即可。 - noz3r0
你确定它失败了吗?如果在PowerShell ISE中运行PSExec,它会抛出一个错误,但仍然可以正常工作。这有其原因,与PSExec输出数据的方式有关,其中一部分输出到标准输出流,另一部分则输出到错误流。不管怎样,你确定它没有工作吗? - TheMadTechnician
我看到你提交了一次编辑,我的最终脚本与你的不同,我明天会试一下并告诉你结果。虽然看起来应该能行。感谢你的勤奋。 - noz3r0
嘿,就这样了。感谢你的帮助和耐心。我试图给你一些赞,但显然我不能这样做。有没有办法将此标记为“已回答”? - noz3r0
在左侧,应该有一个选项,在我的答案旁边标记问题已回答,就在标记上下文的下方。 - TheMadTechnician

7
我知道这个问题是2014年的,我的回答可能无法直接回答用户的问题。但是对于现在遇到这个问题的人来说,我想说如果你正在使用PowerShell,你不需要使用PSExec。既然你已经在PowerShell中了,只需使用Invoke-Command命令即可。
语法如下:
Invoke-Command -ComputerName $Computer -ScriptBlock { C:\Folder\install.bat }

这真的很简单。

*需要在目标服务器上启用PowerShell远程管理。<< 一些人正在使用PSExec运行winrm quickconfig来启用PSRemoting... 所以这仍然是一个有效的问题,"PSExec"和"PSRemoting"这两个东西是不同的。


3
这是一种过于简化的说法。如果install.bat需要进行双重跳转,这种方法将行不通。 - Reuben Tanner
2
“PowerShell远程管理”是一个重要的区别,特别是对于可能没有配置支持它的生产环境而言。默认情况下,Win2016/Win10及更早版本启用了PSExec远程管理,禁用了WinRM。 - Zephan Schroeder

2

试试这个。你需要一个 $,但你用了一个 %。此外,cmd.exe 的调用是不必要的。

    $computers = gc "C:\scripts\computers.txt"

foreach ($computer in $computers) {
if (test-Connection -Cn $computer -quiet) {
    cd C:\pstools
    psexec \\$computer "C:\Folder\install.bat"
} else {
    "$computer is not online"
}

}

误报警告。它不会像那样运行psexec,说它不是有效的cmdlet。有一个命令可以运行可执行文件吗? - noz3r0

0

使用 & (调用) 运算符,以及 &psexec \$computer "C:\Folder\install.bat" 命令。


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