在 powershell 脚本中使用 'mstsc' 打开多个远程会话
Open multiple remote sessions using 'mstsc' in powershell script
我正在尝试编写一个 powershell 脚本,为保存在文本文件中的每个机器名称打开远程桌面连接。当我 运行 脚本时,它只连接到列表中的第一台机器并输出到控制台:CMDKEY: Credential added successfully
一次(不是每台机器一次)。 mstcs
似乎在执行后终止了进程,我不确定我是否以正确的方式添加凭据。谁能指出我正确的方向?
以下是我试图弄清楚发生了什么的一些测试:
- 在
mstsc
之后打印。不打印。过程似乎在之后终止
mstcs
被调用。这似乎是问题的关键。
cmdkey /list
显示我存储的所有凭据及其目标。输出不包括文本文件中定义的所有目标。即使我注释掉 mstsc
,然后 cmdkey /add:$MachineName /user:$User /pass:$Password
似乎只在第一行执行,缺乏更多的控制台输出和 cmdkey /list
没有产生预期的目标就证明了这一点。此外,我在 cmdkey
行之后添加了一个打印语句,它为每一行打印,所以它不会在 运行ning 之后终止(我已经知道,因为 mstcs
在之后执行没有注释掉的这一行)。
# Read from file
$Lines = Get-Content -Path .\machines.txt | Out-String
# For each machine ...
foreach($Line in $Lines){
# Split line, save name and domain
$Tokens = $Line.Split(".")
$MachineName = $Tokens[0]
$Domain = $Tokens[1]
$User = "someDomain\someUsername"
$Password="somePassword"
# Switch username if someOtherDomain
if ($Domain -eq "someOtherDomain"){
$User = "someOtherDomain\someOtherUsername"
}
#set credentials and open connection
cmdkey /add:$MachineName /user:$User /pass:$Password
mstsc /v:$MachineName /console
}
编辑: 我也尝试用 Start-Process -FilePath "$env:windir\system32\mstsc.exe" -ArgumentList "/v:$MachineName" -Wait
替换 mstsc /v:$MachineName
。结果是打开会话,然后脚本没有在控制台中完成,但没有发生任何其他事情。
此行为是由于您使用了 Out-String
。
Get-Content
输出 多个 字符串,文件中每行一个 - 但 Out-String
将它们拼接回 单个 多行字符串:
PS C:\> $machines = Get-Content machines.txt
PS C:\> $machines.GetType().Name # definitely an array
Object[]
PS C:\> $machines.Count # multiple strings in there
4
PS C:\> $machines = Get-Content machines.txt | Out-String
PS C:\> $machines.GetType().Name # now it's just a single string
String
所以你的foreach(){}
循环只运行一次,$MachineName
的值不再是单机名,而是多机名一次包含所有这些行字符串 - 这可能是 mstsc
立即退出的原因:)
从第一行删除 |Out-String
,您的循环将正常运行
我正在尝试编写一个 powershell 脚本,为保存在文本文件中的每个机器名称打开远程桌面连接。当我 运行 脚本时,它只连接到列表中的第一台机器并输出到控制台:CMDKEY: Credential added successfully
一次(不是每台机器一次)。 mstcs
似乎在执行后终止了进程,我不确定我是否以正确的方式添加凭据。谁能指出我正确的方向?
以下是我试图弄清楚发生了什么的一些测试:
- 在
mstsc
之后打印。不打印。过程似乎在之后终止mstcs
被调用。这似乎是问题的关键。 cmdkey /list
显示我存储的所有凭据及其目标。输出不包括文本文件中定义的所有目标。即使我注释掉mstsc
,然后cmdkey /add:$MachineName /user:$User /pass:$Password
似乎只在第一行执行,缺乏更多的控制台输出和cmdkey /list
没有产生预期的目标就证明了这一点。此外,我在cmdkey
行之后添加了一个打印语句,它为每一行打印,所以它不会在 运行ning 之后终止(我已经知道,因为mstcs
在之后执行没有注释掉的这一行)。
# Read from file
$Lines = Get-Content -Path .\machines.txt | Out-String
# For each machine ...
foreach($Line in $Lines){
# Split line, save name and domain
$Tokens = $Line.Split(".")
$MachineName = $Tokens[0]
$Domain = $Tokens[1]
$User = "someDomain\someUsername"
$Password="somePassword"
# Switch username if someOtherDomain
if ($Domain -eq "someOtherDomain"){
$User = "someOtherDomain\someOtherUsername"
}
#set credentials and open connection
cmdkey /add:$MachineName /user:$User /pass:$Password
mstsc /v:$MachineName /console
}
编辑: 我也尝试用 Start-Process -FilePath "$env:windir\system32\mstsc.exe" -ArgumentList "/v:$MachineName" -Wait
替换 mstsc /v:$MachineName
。结果是打开会话,然后脚本没有在控制台中完成,但没有发生任何其他事情。
此行为是由于您使用了 Out-String
。
Get-Content
输出 多个 字符串,文件中每行一个 - 但 Out-String
将它们拼接回 单个 多行字符串:
PS C:\> $machines = Get-Content machines.txt
PS C:\> $machines.GetType().Name # definitely an array
Object[]
PS C:\> $machines.Count # multiple strings in there
4
PS C:\> $machines = Get-Content machines.txt | Out-String
PS C:\> $machines.GetType().Name # now it's just a single string
String
所以你的foreach(){}
循环只运行一次,$MachineName
的值不再是单机名,而是多机名一次包含所有这些行字符串 - 这可能是 mstsc
立即退出的原因:)
从第一行删除 |Out-String
,您的循环将正常运行