这是一个我正在努力解决的相当复杂和令人讨厌的情况,所以我会尽量简化。
情况:我的组织对远程站点的Windows PC使用基于站点的命名约定。这些网站不在域上。命名约定如下:
(站点ID) - (设备用途)(设备编号) - (设备型号)
网站ID限制为5个字符。 设备用途限制为2个字符。 设备型号限制为4个字符。
因此,示例设备名称可能如下所示:
ABCDE-FG12-9876
问题:由于规划不当,许多设备错误地将名称的(设备编号)元素复制了。因此,使用上面的示例,我可能在站点ABCDE上有两个名为sequenceScore
的设备。我需要在不必手动触摸每个设备的情况下解决此问题。
PLAN:我正在开发一个PowerShell脚本,我想执行以下操作:
问题:我已经到了构建数组并尝试检查其内容的问题,并且由于我无法弄清楚的原因,它只是只添加了该机器的名称在上运行到阵列,而没有正确添加站点子网中的其余计算机。我已经阅读了代码,直到我的眼睛交叉,并尝试重新使用来自StackOverflow和其他网站的样本,我觉得我只是在旋转轮胎而无处可去。
我当然愿意接受任何关于如何实现目标的替代想法,但作为参考,到目前为止,我的代码在下面。现在,我只是想将referenceSequence
的内容输出到屏幕以验证是否正在捕获正确的信息。
ABCDE-FG12-9876
答案 0 :(得分:0)
我使用以下内容进行重命名,
$a = Import-Csv c:\ServerNames.csv -Header OldName, NewName
Foreach ( $Server in $a ) {Rename-Computer -ComputerName $Server.OldName -NewName $Server.NewName -DomainCredential Domain\username -Force -Restart}
现在这有它的垮台因为你必须给它一个CSV,但是你把旧的名字/ IP地址放在第1列,然后把新的一个放在第二列并运行它。预先有更多的工作,但脚本中的逻辑更少失败。
答案 1 :(得分:0)
由于所有子网似乎都是/ 24个IPv4子网,因此您可以通过使用该功能获取主机IP地址(字符串)并返回新的(整数)设备号来简化代码:
$pattern = '^(.{5}-.{2})(\d+)(-.{4})$'
function Scan-Subnet($ip) {
$bytes = ([ipaddress]$ip).GetAddressBytes()
1..254 | % {
$bytes[3] = $_
$addr = [ipaddress]$bytes
if (Test-Connection $addr -Count 1 -ErrorAction SilentlyContinue) {
Get-WMIObject -Class Win32_OperatingSystem -Computer $addr |
select @{n='DeviceNumber';e={[int]($_.CSName -replace $pattern,'$2')}} |
select -Expand DeviceNumber
}
} | sort | select -last 1 | % { $_ + 1 }
}
$pattern
被定义为具有3个组的全局变量,因此它可以用于提取设备编号和构建新名称(见下文)。
主机IP地址可以通过WMI确定,因此你可以调用这样的函数:
$myIP = Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter 'IPEnabled=True' |
select -Expand IPAddress |
select -First 1
$deviceNumber = Scan-Subnet $myIP
并将计算机重命名为:
if ($deviceNumber -ne $null) {
$newname = $env:COMPUTERNAME -replace $pattern, "`$1$deviceNumber`$3"
Rename-Computer -NewName $newname -Restart
}
由于Rename-Computer
在PowerShell v3之前不可用,您还可以使用netdom
:
& netdom $env:COMPUTERNAME /NewName:$newname /Reboot