【问题标题】:Add 'Next Available AD Computer' to power-shell script将“下一个可用的 AD 计算机”添加到 power-shell 脚本
【发布时间】:2019-07-13 19:12:11
【问题描述】:

目前,我正在尝试向我的 powershell 脚本添加一个函数,其目标如下:

在尚未添加到域的计算机上,让它根据用户的输入在本地 AD 服务器(非天蓝色)中搜索下一个可用名称。

我过去曾尝试过使用数组但失败了,我想在此使用 Get-ADComputer cmdlet,但我不知道如何实现它。

$usrinput = Read-Host 'The current PC name is $pcname , would you like to rename it? (Y/N)'
if($usrinput -like "*Y*") {
    Write-Output ""
    $global:pcname = Read-Host "Please enter the desired PC Name"
    Write-Output ""

    $userinput = Read-Host "You've entered $pcname, is this correct? (Y/N)"
    if($usrinput -like "*N*") {
    GenName
    #name of the parent function
}
Write-Output ""

上面的代码是一个更大的脚本的一部分,它解析一个计算机名称并最终将其分配给正确的 OU。

我们的命名方案是这样的:BTS-ONE-LAP-000

所以它是:部门 - 位置 - 设备类型 - 设备计数

然后,代码将获取第一部分“BTS-ONE”并解析它以找到它应该去的正确 OU,然后使用 Add-Computer cmdlet 分配它。它还会将机器重命名为用户输入的任何内容 ($pcname)。

因此,在解析名称之前,我希望它搜索 AD 中的所有当前名称。

因此,用户可以输入:“BTS-ONE-LAP”,它会自动找到下一个可用的设备计数,并将其添加到名称中。所以,它会自动生成“BTS-ONE-LAP-041”。

补充说明:

我用过Get-ADComputer -Filter 'Name -like "BTS-ONE-LAP-*"' | FT Name,输出是

Name           
----           
BTS-ONE-LAP-001
BTS-ONE-LAP-002
BTS-ONE-LAP-006
BTS-ONE-LAP-007
BTS-ONE-LAP-009
BTS-ONE-LAP-010
BTS-ONE-LAP-022
BTS-ONE-LAP-024
BTS-ONE-LAP-025
BTS-ONE-LAP-028
BTS-ONE-LAP-029
BTS-ONE-LAP-030
BTS-ONE-LAP-031
BTS-ONE-LAP-032
BTS-ONE-LAP-034
BTS-ONE-LAP-035
BTS-ONE-LAP-036
BTS-ONE-LAP-037
BTS-ONE-LAP-038
BTS-ONE-LAP-039
BTS-ONE-LAP-040
BTS-ONE-LAP-041
BTS-ONE-LAP-050
BTS-ONE-LAP-051

我不知道如何解析这个,所以代码知道 BTS-ONE-LAP-003 可用(我对数组很糟糕)。

【问题讨论】:

  • 您可能会发现Get-ADComputer-filter 参数很有用。
  • 如果您无法处理这种基本操作,您将无法获得可行的解决方案。您的替代方法是尝试一次检索每个单独的数字,直到调用 Get-ADComputer 失败。这是一种真的 糟糕的方法,而且扩展性不好。
  • 另外,如果您想进一步解析数据,请勿使用Format-* cmdlet 进行输出。 PowerShell 生成对象,而不是文本,当你有对象时,你可以检查它们的属性,并在检查后操作整个对象。
  • Sort-Object cmdlet 将对这些名称进行整齐排序。抓住最后一个并在后缀中添加一个。
  • 试试(Get-ADComputer ... | Sort-Object Name)[-1]

标签: powershell active-directory


【解决方案1】:
$list = (Get-ADComputer -Filter 'Name -like "BTS-ONE-LAP-*"' | Sort-Object Name[-1])

$i = 1
$found = $false
Foreach($Name in $list.Name)
{
    while($i -eq [int]$Name.Split("-")[3].Split("-")[0])
    {
        $i++
    }
}
$i

上面的代码会遍历列表中的每个名字,当它发现集合中的第 3 台计算机不是 #3 计算机时会停止。

例子:

BTS-ONE-LAP-001 | $i = 1
BTS-ONE-LAP-002 | $i = 2
BTS-ONE-LAP-006 | $i = 3

它将BTS-ONE-LAP-006拆分为006,并将其转换为整数,使其为6。 由于 6 不等于 3,我们知道 BTS-ONE-LAP-003 可用。

【讨论】:

  • 比较两个整数值时,我不会使用(字符串)Regex -match 运算符。 -eq 应该更适合这里。
【解决方案2】:

另一种方法是创建一个可重用的函数,如下所示:

function Find-FirstAvailableNumber ([int[]]$Numbers, [int]$Start = 1) {
    $Numbers | Sort-Object -Unique | ForEach-Object {
        if ($Start -ne $_) { return $Start }
        $Start++
    }
    # no gap found, return the next highest value
    return $Start
}

# create an array of integer values taken from the computer names
# and use the helper function to find the first available number
$numbers = (Get-ADComputer -Filter 'Name -like "BTS-ONE-LAP-*"') | 
            ForEach-Object { [int](([regex]'(\d+$)').Match($_.Name).Groups[1].Value) }

# find the first available number or the next highest if there was no gap
$newNumber = Find-FirstAvailableNumber $numbers

# create the new computername using that number, formatted with leading zero's
$newComputerName = 'BTS-ONE-LAP-{0:000}' -f $newNumber

使用您的示例列表,$newComputerName 将变为 BTS-ONE-LAP-003

请注意,并非用户使用Read-Host 输入的所有内容都是有效的计算机名称。您应该添加一些检查以查看建议的名称是否可以接受,或者全部跳过建议的名称,因为您的所有机器都命名为“BTS-ONE-LAP-XXX”。
Naming conventions in Active Directory for computers, domains, sites, and OUs

【讨论】:

  • 谢谢,这实际上已经是可重用功能的一部分(将其修剪到不起作用的部分),但我根据您的建议做了一些修改。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-01
  • 2023-03-03
  • 2020-11-09
  • 1970-01-01
  • 2017-11-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多