这是一个相当复杂和讨厌的情况,我试图解决,所以我将尽量简化。
情况:我的组织对远程站点上的windows使用基于站点的命名约定。这些站点不在域上。命名约定如下:
(站点ID)-(设备用途)(设备编号)-(设备模型)
站点ID限制为5个字符。设备用途限制为2个字符。设备模型限制为4个字符。
因此,一个示例设备名称可能如下所示:
ABCDE-FG12-9876
问题:由于计划不当,许多设备错误地复制了名称的(设备编号)元素。因此,使用上面的示例,我可能在站点ABCDE上有两个设备,它们都名为ABCDE-FG12-9876。我需要修复这一点,而不必手动触摸每个设备。
计划:,我正在编写一个PowerShell脚本,我想做以下工作:
问题:--我已经到了构建数组并试图检查其内容的地步,由于无法确定的原因,它只是将脚本运行的机器的名称添加到数组中,而没有正确地在站点子网中添加其余的机器。我已经阅读了代码,直到我的眼睛交叉,并尝试重复使用样本从StackOverflow和其他网站,我觉得我只是在旋转我的轮胎,没有任何进展。
当然,对于如何实现我的目标,我对任何其他的想法都持开放态度,但作为参考,我的代码目前还在下面,我只是尝试将$sitemachines的内容输出到屏幕上,以验证是否捕获了正确的信息。
Function Iterate-Subnet($Subnet) { #in the format of "10.10.10."
$arrIPs = @();$arrValid = @() #Creates 2 arrays, one to hold the IP
#addresses and the other to hold confirmed
#Windows machines
For($x=1; $x -lt 254; $x++) {
#Starting at 1 and incrementing to 254, each time building a new IP
#address based on the subnet
$IPAddress = $Subnet + $x;$arrIPs += $IPAddress
}
ForEach ($IPfound in $arrIPs) {
$ping = Get-WMIObject -Class Win32_PingStatus -Filter "Address='$IPfound'" #Ping each IP address in the subnet
If ($ping.StatusCode -eq "0") {
#Attempt to connect to each online machine using WMI, this
#confirms whether it's a Windows machine
$checkOS = Get-WMIObject -Class Win32_OperatingSystem -ComputerName "$IPfound" -ErrorAction SilentlyContinue
#Add this computer name to the valid array
If ($checkOS -ne $null) {$arrValid += @($checkOS.CSName)}
}
}
#Remove any duplicate entries, this accounts for any multihomed machines
$arrValid = $arrValid | Select-Object -Unique
#Return the valid array to any script you choose to call this function from
return $arrValid
}
#Split the computer name at the device position number
#and store the beginning and end into two variables
$computer = hostname
$cname1 = $computer.substring(0,8)
$cname2 = $computer.substring($computer.length -5,5)
#Find and define the site subnet for pingsweep
#referencing current machine IP Address
$getip = Test-Connection -ComputerName $computer -Count 1
$ip = $getip.IPV4Address.IPAddressToString
$IPByte = $ip.Split(".")
$sitesub = ($IPByte[0]+"."+$IPByte[1]+"."+$IPByte[2]+".")
#build and retrieve the list of site machines
#from the function Iterate-Subnet
$sitemachines = Iterate-Subnet -Subnet "$sitesub"
Start-Sleep -s 30
$sitemachines.length
$sitemachines发布于 2015-06-29 21:05:00
我用下面这个来重命名,
$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列中,将新的地址放在第二列中,然后运行它。前面有更多的工作,但脚本中失败的逻辑较少。
发布于 2015-06-29 22:13:41
由于您的所有子网似乎都是/24 IPv4子网,您可以通过让函数获取主机IP地址(string)并返回新的(整数)设备号来简化代码:
$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 /Reboothttps://stackoverflow.com/questions/31125219
复制相似问题