PowerShell SSH远程改计算机名变量不识别及批量执行咨询
问题1:修复wmic命令中变量无法解析的问题
单引号包裹的字符串属于PowerShell字面量类型,不会执行任何变量插值、特殊字符解析,因此写在单引号内的$inputID会被原样发送到目标主机,最终执行的重命名操作会把计算机名改成字面值的$inputID,达不到预期效果。
有两种零副作用的修复方案,既可以保留wmic要求的"%computername%"双引号格式,又能让$inputID正常解析:
- 字符串拼接法(无转义、不易出错)
将不需要解析的固定命令段用单引号定义,直接把变量拼接在字符串末尾:$Command = 'wmic computersystem where caption="%computername%" rename ' + $inputID - 双引号字符串转义法
整段命令用双引号包裹(双引号作用域会自动解析内部变量),命令中需要保留的字面双引号用连续两个双引号转义:
两种方法最终生成的命令格式完全一致,不会破坏wmic的参数要求。$Command = "wmic computersystem where caption=""%computername%"" rename $inputID"
问题2:改造为批量处理所有CSV主机的脚本
原脚本为单条匹配逻辑,需要手动输入ID定位单条记录执行操作,改造为批量处理需要删除手动输入、单条匹配的代码,直接遍历CSV所有条目,同时注意规避几个常见运行问题:
- 凭据对象、SSH可信主机清理操作只在脚本初始化时执行一次,不要在循环内重复初始化、反复清理可信主机
- 每台主机的SSH会话建立、命令执行、会话清理操作全部放在循环内完成,避免会话堆积占用资源
- 增加会话建立失败的判断逻辑,遇到连接失败的主机直接跳过,不影响后续主机的处理
改造后的完整批量脚本如下:
# 导入主机列表 $db = Import-Csv -Path ".\host.csv" # 提前定义固定访问凭据,避免重复初始化 $User = "user" $Password = "Pass" $secpasswd = ConvertTo-SecureString $Password -AsPlainText -Force $Credentials = New-Object System.Management.Automation.PSCredential($User, $secpasswd) # 脚本启动时统一清理一次SSH可信主机缓存 Get-SSHTrustedHost | Remove-SSHTrustedHost # 逐台遍历主机执行操作 foreach ($entry in $db) { Write-Host "正在处理主机:目标名称 $($entry.ID),IP $($entry.IP)" # 生成重命名命令 $Command = 'wmic computersystem where caption="%computername%" rename ' + $entry.ID # 建立SSH会话,连接失败时跳过当前主机 $Session = New-SSHSession -ComputerName $entry.IP -Credential $Credentials -AcceptKey:$true if (-not $Session) { Write-Warning "主机 $($entry.IP) 连接失败,已跳过" continue } # 执行重命名命令 Invoke-SSHCommand -Index $Session.SessionId -Command $Command # 执行完成后移除会话,释放资源 Remove-SSHSession -SessionId $Session.SessionId | Out-Null }
注意:脚本默认要求host.csv内每条记录包含
ID(目标主机的新名称)、IP(主机可连通的IP地址)两个字段;wmic的重命名操作需要主机重启后才会完全生效,如需自动触发重启,可以在命令执行后追加一条远程重启命令即可。
内容的提问来源于stack exchange,提问作者user12428212
相关产品推荐
相关产品推荐

