我今天正在努力让这个简单的(?)函数工作。
我有一个PowerShell脚本,可以从基于txt的文件中读取计算机名称。当通过以下单行从 PowerShell 会话运行时,它工作正常:
./"Server Health Check.ps1" -List One-off.txt
如您所见,它有一个很长的文件名,因此用引号括起来。
但是,我正在构建一个带有单选框的 PowerShell GUI 表单,该单选框将传递将用于调用脚本的文本文件的选择。诀窍是,脚本需要使用备用管理员帐户运行,我不清楚如何使其工作。
对于我的另一个不使用的脚本,我知道我可以使用如下内容,这使用旧的 DOS"runas",但是,它不适用于 -list 函数。
invoke-command -scriptblock {runas.exe /user:domain$Env:Username"admin" "powershell.exe -file "\Serverc$LONG FOLDERServer Health Check.PS1""}
那么,简而言之,如何使用从命令行读取参数 (-List) 的备用凭据启动脚本?我也热衷于保留我的目录结构,其中包括带有空格的文件夹。该脚本的标题为:"服务器运行状况检查.ps1"
我尝试的最后一件事是以下内容
$ScriptPath = "C:SCRIPTS FOLDERServer Health Check.ps1"
$ArgList = "-List C:SCRIPTS FOLDEROne-off.txt"
Invoke-Command -filepath $ScriptPath -Credential DragonBallDomain$Env:UserName"Admin" -ArgumentList $ArgList
结果是以下消息:
Invoke-Command : Parameter set cannot be resolved using the specified named parameters.
我几乎可以肯定这可以通过调用命令或启动过程来实现,这只是获得正确格式的问题?我可能在启动过程或调用命令的试验中某处缺少/或 ' 或 "。
任何帮助表示赞赏!
4 月 30 日更新:
我已经尝试了更多来完成这项工作,我已经接近了,但仍然没有完全实现。
$LongScriptPath = resolve-path Script.ps1
$LongFolderPath = \UNCPATH TO FOLDERWITH LONG NAME
start-process -filepath powershell.exe -argumentlist " -file``"$($FilePath.path)`"" -cred DOMAINUSERID -WorkingDirectory "$LongFolderPath"
添加 -credential 会导致错误,指出 -file 参数无效。我相信有一种方法可以做到这一点。
注意:在要求变得更加清晰后完全重写。
若要在本地以其他用户身份运行命令,请使用 Start-Process -Credential ...
原则上,这就是您在更新中尝试的内容,但是传递参数的方式存在问题;请尝试以下操作:
$LongScriptPath = resolve-path Script.ps1
$LongFolderPath = '\UNCPATH TO FOLDERWITH LONG NAME'
start-process `
powershell.exe `
-ArgumentList '-file', $LongScriptPath, '-List', 'One-off.txt' `
-Credential DOMAINUSERID `
-WorkingDirectory $LongFolderPath
完成这项工作的关键是通过
Start-Process
的-ArgumentList
参数将所有要传递给powershell.exe
的参数作为数组传递,这意味着参数必须,
分隔。- 请注意数组始终在表达式模式下解析,这意味着文本字符串元素(如
-file
和-List
)必须用引号括起来。 - 通常,了解PowerShell的两种基本分析模式(参数模式和表达式模式)之间的区别非常重要,并且在以下情况下应用了哪种模式 - 请参阅 https://technet.microsoft.com/en-us/library/hh847892.aspx
- 请注意数组始终在表达式模式下解析,这意味着文本字符串元素(如
添加
-Wait
以等待脚本完成; 默认情况下,Start-Process
是异步的(所有名为Start-*
的 PS cmdlet 都是异步的)。- 警告:对于以其他用户身份调用的命令,只能从提升的提示符开始等待。
如果不是,该命令仍将执行,但会异步执行,并且您将在当前控制台中收到Access denied
错误消息;实际上,-Wait
被忽略。
- 警告:对于以其他用户身份调用的命令,只能从提升的提示符开始等待。
仅当未以其他用户身份运行时:如果要在当前控制台窗口中运行脚本,请添加
-NoNewWindow -Wait
; 默认情况下,Start-Process
会为控制台应用程序(如powershell.exe
和cmd.exe
)打开一个新窗口。- 如果确实以其他用户身份运行该命令,则会静默忽略
-NoNewWindow
。
- 如果确实以其他用户身份运行该命令,则会静默忽略
至于原始症状以及为什么使用 Invoke-Command
以其他用户身份在本地运行命令是不明智的:
Invoke-Command -Credential ...
还要求指定-ComputerName
参数。- 运行
Get-Help Invoke-Command
以查看涉及-Credential
参数的所有参数集。OP最初的命令只有-Credential
,但没有-ComputerName
,这导致PS抱怨没有参数集可以明确识别。
使用 - 运行
-ComputerName
后,将始终使用 PowerShell 远程处理,即使您指定.
(本地计算机)作为唯一的目标计算机也是如此。- 使用远程处理有两个含义:
- 默认情况下,远程处理不可用,必须在目标计算机(在本例中为本地计算机)上配置远程处理。
- 使用远程处理需要使用管理员权限进行调用。
- 使用远程处理有两个含义:
总之:
虽然您可以使用
Invoke-Command
执行纯本地调用,但您不能以其他用户身份执行此操作,因为这总是涉及远程处理。相比之下,
Start-Process
仅存在于本地运行命令,可以选择作为其他用户运行命令。