PowerShell脚本:$serial变量为数组而非字符串的问题求助
解决PowerShell脚本中$serial返回对象而非纯字符串的问题
你的问题出在获取BIOS序列号的方式错误,Select-String SerialNumber并没有返回你想要的纯字符串序列号,而是返回了一个MatchInfo对象,所以当你拼接字符串时,PowerShell会把这个对象的默认字符串表示(也就是@{SerialNumber=XXX})拼进去,导致重命名出错。
错误原因分析
Get-WmiObject Win32_Bios返回的是包含BIOS信息的对象,其中SerialNumber是这个对象的一个属性。而Select-String是用来在文本中匹配字符串的命令,它会把输入对象转换成字符串后进行匹配,最终返回的是匹配结果对象,不是属性的纯值。这就是为什么Write-Host显示看似正常(它会做默认格式化),但实际赋值后$serial是对象/特殊格式的原因。
解决方案
你需要直接提取SerialNumber属性的纯字符串值,有两种简单可靠的方式:
方式1:直接访问对象属性
最直接的写法,跳过多余命令,直接获取属性值:
$serial = (Get-WmiObject Win32_Bios -ComputerName $_.name).SerialNumber
更推荐用现代的Get-CimInstance替代Get-WmiObject(WMI系列cmdlet已逐步被CIM取代):
$serial = (Get-CimInstance Win32_Bios -ComputerName $_.name).SerialNumber
方式2:用Select-Object -ExpandProperty提取属性
如果你习惯管道写法,可以用-ExpandProperty参数直接获取属性的纯值:
$serial = Get-CimInstance Win32_Bios -ComputerName $_.name | Select-Object -ExpandProperty SerialNumber
优化后的完整脚本
另外建议增加空值判断,避免部分机器无序列号导致重命名失败:
Import-Module ActiveDirectory Get-ADComputer -Filter {Name -like 'DESKTOP-*'} -Properties DNSHostName | Select Name, DNSHostName | ForEach-Object { $rtn = Test-Connection -CN $_.dnshostname -Count 1 -BufferSize 16 -Quiet if ($rtn) { # 直接判断布尔值,无需-match 'True' $serial = (Get-CimInstance Win32_Bios -ComputerName $_.name).SerialNumber if (-not [string]::IsNullOrWhiteSpace($serial)) { $newName = "C000$serial" Rename-Computer -ComputerName $_.name -NewName $newName -DomainCredential $mycreds -Force -Restart } else { Write-Warning "机器 $($_.name) 未获取到BIOS序列号,跳过重命名" } } }
额外小优化
Test-Connection的-Quiet返回布尔值,直接用if ($rtn)判断更简洁;- 单独定义
$newName变量,提升代码可读性。
内容的提问来源于stack exchange,提问作者user6888062
相关产品推荐
相关产品推荐

