首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在本地子网中查找可用设备名并重命名设备

在本地子网中查找可用设备名并重命名设备
EN

Stack Overflow用户
提问于 2015-06-29 20:43:46
回答 2查看 200关注 0票数 2

这是一个相当复杂和讨厌的情况,我试图解决,所以我将尽量简化。

情况:我的组织对远程站点上的windows使用基于站点的命名约定。这些站点不在域上。命名约定如下:

(站点ID)-(设备用途)(设备编号)-(设备模型)

站点ID限制为5个字符。设备用途限制为2个字符。设备模型限制为4个字符。

因此,一个示例设备名称可能如下所示:

ABCDE-FG12-9876

问题:由于计划不当,许多设备错误地复制了名称的(设备编号)元素。因此,使用上面的示例,我可能在站点ABCDE上有两个设备,它们都名为ABCDE-FG12-9876。我需要修复这一点,而不必手动触摸每个设备。

计划:,我正在编写一个PowerShell脚本,我想做以下工作:

  1. 根据当前机器的IP地址标识站点的/24子网。
  2. 使用该子网来平平该子网上的所有活动窗口机器,并将它们的机器名称放入数组中。
  3. 根据该数组中的数据,确定第一个可用的设备号(设备号),重命名设备并重新启动它。

问题:--我已经到了构建数组并试图检查其内容的地步,由于无法确定的原因,它只是将脚本运行的机器的名称添加到数组中,而没有正确地在站点子网中添加其余的机器。我已经阅读了代码,直到我的眼睛交叉,并尝试重复使用样本从StackOverflow和其他网站,我觉得我只是在旋转我的轮胎,没有任何进展。

当然,对于如何实现我的目标,我对任何其他的想法都持开放态度,但作为参考,我的代码目前还在下面,我只是尝试将$sitemachines的内容输出到屏幕上,以验证是否捕获了正确的信息。

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

发布于 2015-06-29 21:05:00

我用下面这个来重命名,

代码语言:javascript
复制
$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列中,将新的地址放在第二列中,然后运行它。前面有更多的工作,但脚本中失败的逻辑较少。

票数 0
EN

Stack Overflow用户

发布于 2015-06-29 22:13:41

由于您的所有子网似乎都是/24 IPv4子网,您可以通过让函数获取主机IP地址(string)并返回新的(整数)设备号来简化代码:

代码语言:javascript
复制
$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确定,因此您可以按如下方式调用该函数:

代码语言:javascript
复制
$myIP = Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter 'IPEnabled=True' |
        select -Expand IPAddress |
        select -First 1

$deviceNumber = Scan-Subnet $myIP

并将计算机重命名如下:

代码语言:javascript
复制
if ($deviceNumber -ne $null) {
  $newname = $env:COMPUTERNAME -replace $pattern, "`$1$deviceNumber`$3"
  Rename-Computer -NewName $newname -Restart
}

由于Rename-Computer在PowerShell v3之前不可用,所以也可以使用netdom

代码语言:javascript
复制
& netdom $env:COMPUTERNAME /NewName:$newname /Reboot
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31125219

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档