【问题标题】:PowerShell Set-ADComputer description based on the inputPowerShell Set-ADComputer 基于输入的描述
【发布时间】:2018-04-19 19:53:53
【问题描述】:

我有一个通过 Active Directory 计算机对象运行以收集信息的代码。然后在 Active Directory 描述字段中更新该信息的一部分。 我的问题是,当我收到 Exception.Message 时,计算机的 AD 对象仍会使用最后找到的计算机信息进行更新。 我想知道我该怎么做:

  • 出现 Exception.Message 时更新 AD 描述
  • 使用填充的系统信息更新广告说明

附件是我正在使用的脚本,但不知道将两个 Set-ADComputer 语句的输出放在哪里

    # Getting computers from Active Directory
    $Computers = Get-ADComputer -Filter {Enabled -eq $true} | select -expand name
    Foreach($computer in $computers)
    # Checking if the computer is Online      
    {
    if(!(Test-Connection -ComputerName $computer -BufferSize 16 -Count 1 -ea 0 -quiet))
    {write-host "Cannot reach $Computer is offline" -ForegroundColor red}
       else {
    $Output = @()
    Try{
    $xx = Get-WmiObject win32_computersystem -ComputerName $Computer -ErrorAction Stop
    $in = Get-WmiObject Win32_OperatingSystem -ComputerName $Computer -ErrorAction Stop
    $mc = Get-WmiObject -class Win32_NetworkAdapterConfiguration -Filter "IPEnabled='True'" -ComputerName $Computer -ErrorAction Stop
    $sr = Get-WmiObject win32_bios -ComputerName $Computer -ErrorAction Stop
    $Xr = Get-WmiObject –class Win32_processor -ComputerName $Computer -ErrorAction Stop 
    $ld = Get-ADComputer $Computer -properties Name,Lastlogondate,ipv4Address,enabled,description,DistinguishedName -ErrorAction Stop
    $r = "{0} GB" -f ((Get-WmiObject Win32_PhysicalMemory -ComputerName $Computer -ErrorAction Stop | Measure-Object Capacity  -Sum).Sum / 1GB)
    $x = Get-WmiObject win32_computersystem -ComputerName $Computer -ErrorAction Stop | select @{Name = "Type";Expression = {if (($_.pcsystemtype -eq '2')  )
    {'Laptop'} Else {'Desktop Or Other'}}},Manufacturer,@{Name = "Model";Expression = {if (($_.model -eq "$null")  ) {'Virtual'} Else {$_.model}}},username
    $t= New-Object PSObject -Property @{
    SerialNumber = $sr.serialnumber -replace "-.*"
    Computername = $ld.name
    IPaddress = $ld.ipv4Address
    MACaddress = $mc.MACAddress
    Enabled = $ld.Enabled
    Description = $ld.description
    OU = $ld.DistinguishedName.split(',')[1].split('=')[1] 
    DC = $xx.domain
    Type = $x.type
    Manufacturer = $x.Manufacturer
    Model = $x.Model
    RAM = $R
    ProcessorName = ($xr.name | Out-String).Trim()
    NumberOfCores = ($xr.NumberOfCores | Out-String).Trim()
    NumberOfLogicalProcessors = ($xr.NumberOfLogicalProcessors | Out-String).Trim()
    Addresswidth = ($xr.Addresswidth | Out-String).Trim()
    Operatingsystem = $in.caption
    InstallDate = ([WMI] '').ConvertToDateTime($in.installDate)
    LastLogonDate = $ld.lastlogondate
    LoggedinUser = $x.username
    }
    $Output += $t
    }
    Catch [Exception]
    {
    $ErrorMessage = $_.Exception.Message
    Add-Content -value "$Computer, $ErrorMessage, skipping to next" $txt
    Set-ADComputer $Computer -Description $ErrorMessage
    }
    }
    # Output file location to be chnaged as needed
    $file="C:\scripts\reports\AD-Inentory_$((Get-Date).ToString('MM-dd-yyyy')).csv"
    $txt="c:\scripts\reports\AD-Inentory-error_$((Get-Date).ToString('MM-dd-yyyy')).txt"
    $desc="$($mc.MACAddress) ( $($sr.serialnumber -replace "-.*") ) $($x.Model) | $((Get-Date).ToString('MM-dd-yyyy'))"
    # Properties to be included in the output file
    $Output | select Computername,Enabled,Description,IPaddress,MACaddress,OU,DC,Type,SerialNumber,Manufacturer,Model,RAM,ProcessorName,NumberOfCores,NumberOfLogicalProcessors,Addresswidth,Operatingsystem,InstallDate,LoggedinUser,LastLogonDate | export-csv -Append $file -NoTypeInformation 
    Set-ADComputer $Computer -Description $desc -verbose
    }

【问题讨论】:

  • 看来你的逻辑有点奇怪,如果电脑离线,你打算怎么做,完全跳过或者更新上面的描述?

标签: powershell active-directory system


【解决方案1】:

看起来它出现问题行为的原因是它正在捕获错误,并根据需要设置错误的描述。

但是,它会继续评估 catch 和 else 块之外的代码,因为它在当前计算机上失败了,用于构建描述变量的变量仍然包含来自先前计算机的数据,该数据成功然后更新再次出现故障的计算机。

您可以通过使用 catch 块底部的 continue 语句跳过该迭代的其余代码并移至循环中的下一项来解决此问题。

该解决方案如下所示:

Catch [Exception]
{
    $ErrorMessage = $_.Exception.Message
    Add-Content -value "$Computer, $ErrorMessage, skipping to next" $txt
    Set-ADComputer $Computer -Description $ErrorMessage
    ## add continue statement here
    continue
}

continue 声明文档here 和示例here

另一种选择是重组代码以确保不会发生这种情况,如下所示。

我认为这将解决您的问题并完成您想要实现的目标。我在代码中围绕我所做的更改(用 ## 表示)添加了 cmets,请随时提出问题。

我建议您使用更具描述性的变量名称。

## No Need to define these in the foreach loop
# Output file location to be chnaged as needed
$file = "C:\scripts\reports\AD-Inentory_$((Get-Date).ToString('MM-dd-yyyy')).csv"
$txt = "c:\scripts\reports\AD-Inentory-error_$((Get-Date).ToString('MM-dd-yyyy')).txt"

# Getting computers from Active Directory

## Update to use pipeline
Get-ADComputer -Filter {Enabled -eq $true} | Foreach-Object {

    $computer = $_.Name

    if(!(Test-Connection -ComputerName $computer -BufferSize 16 -Count 1 -ea 0 -quiet))
    {
        write-host "Cannot reach $Computer is offline" -ForegroundColor red
    }
    else
    {
        Try
        {
            ## No Longer Need this because we are uisng the pipe line
            #$Output = @()

            $xx = Get-WmiObject win32_computersystem -ComputerName $Computer -ErrorAction Stop
            $in = Get-WmiObject Win32_OperatingSystem -ComputerName $Computer -ErrorAction Stop
            $mc = Get-WmiObject -class Win32_NetworkAdapterConfiguration -Filter "IPEnabled='True'" -ComputerName $Computer -ErrorAction Stop
            $sr = Get-WmiObject win32_bios -ComputerName $Computer -ErrorAction Stop
            $Xr = Get-WmiObject –class Win32_processor -ComputerName $Computer -ErrorAction Stop
            $ld = Get-ADComputer $Computer -properties Name, Lastlogondate, ipv4Address, enabled, description, DistinguishedName -ErrorAction Stop
            $r = "{0} GB" -f ((Get-WmiObject Win32_PhysicalMemory -ComputerName $Computer -ErrorAction Stop | Measure-Object Capacity  -Sum).Sum / 1GB)
            $x = Get-WmiObject win32_computersystem -ComputerName $Computer -ErrorAction Stop | select @{Name = "Type"; Expression = {if (($_.pcsystemtype -eq '2')  )
                    {'Laptop'} Else {'Desktop Or Other'}}
            }, Manufacturer, @{Name = "Model"; Expression = {if (($_.model -eq "$null")  ) {'Virtual'} Else {$_.model}}}, username

            ## Output on creation
            New-Object PSObject -Property @{
                SerialNumber              = $sr.serialnumber -replace "-.*"
                Computername              = $ld.name
                IPaddress                 = $ld.ipv4Address
                MACaddress                = $mc.MACAddress
                Enabled                   = $ld.Enabled
                Description               = $ld.description
                OU                        = $ld.DistinguishedName.split(',')[1].split('=')[1]
                DC                        = $xx.domain
                Type                      = $x.type
                Manufacturer              = $x.Manufacturer
                Model                     = $x.Model
                RAM                       = $R
                ProcessorName             = ($xr.name | Out-String).Trim()
                NumberOfCores             = ($xr.NumberOfCores | Out-String).Trim()
                NumberOfLogicalProcessors = ($xr.NumberOfLogicalProcessors | Out-String).Trim()
                Addresswidth              = ($xr.Addresswidth | Out-String).Trim()
                Operatingsystem           = $in.caption
                InstallDate               = ([WMI] '').ConvertToDateTime($in.installDate)
                LastLogonDate             = $ld.lastlogondate
                LoggedinUser              = $x.username
            }

            ## Only do this kind of update if it hasnt failed yet
            $desc = "$($mc.MACAddress) ( $($sr.serialnumber -replace "-.*") ) $($x.Model) | $((Get-Date).ToString('MM-dd-yyyy'))"
            # Properties to be included in the output file
            Set-ADComputer $Computer -Description $desc -verbose

            ## No longer need this
            # $t
        }
        Catch [Exception]
        {
            $ErrorMessage = $_.Exception.Message
            Add-Content -value "$Computer, $ErrorMessage, skipping to next" $txt
            Set-ADComputer $Computer -Description $ErrorMessage
            continue
        }
    }
} | select Computername, Enabled, Description, IPaddress, MACaddress, OU, DC, Type, SerialNumber, Manufacturer, Model, RAM, ProcessorName, NumberOfCores, NumberOfLogicalProcessors, Addresswidth, Operatingsystem, InstallDate, LoggedinUser, LastLogonDate | export-csv -Append $file -NoTypeInformation

【讨论】:

  • 还有一些其他的事情我想提出,但没有时间。但是,您应该考虑使用 cim 命令而不是 wmiobject 命令。 WMI is old and CIM is new 两者都是 WMI,但 CIM 命令较新。
  • 我看到了您建议的代码更改。我已合并更改并运行它。我的发现是: - 必须将 {} 添加到“{continue}” - 脚本运行良好,但随机出现 Get-ADComputer:服务器返回以下错误:无效的枚举上下文。 - 当检测到错误的计算机对象时,export-csv 会记录空格
  • @GregoryMotyka 这看起来像是一个不同的问题我会从搜索开始我发现this 看起来像是 AD 索引和搜索页面大小的问题。最初搜索时有大量关于此的文章,只需查找错误即可。
【解决方案2】:

查看包含 continue 语句的建议后,我能够使用以下最终脚本解决我的问题:

# Output file location to be changed as needed
$file="C:\scripts\reports\AD-Inentory_$((Get-Date).ToString('MM-dd-yyyy')).csv"
$txt="c:\scripts\reports\AD-Inentory-error_$((Get-Date).ToString('MM-dd-yyyy')).txt"

# Getting computers from Active Directory
$Computers = Get-ADComputer -Filter {Enabled -eq $true} | select -expand name

  Foreach($computer in $computers){

if(!(Test-Connection -ComputerName $computer -BufferSize 16 -Count 1 -ea 0 -quiet))
 {
 write-host "Cannot reach $Computer is offline" -ForegroundColor red
 }
 else
 {

$Output = @()

    Try
    {
        $xx = Get-WmiObject win32_computersystem -ComputerName $Computer -ErrorAction Stop
        $in = Get-WmiObject Win32_OperatingSystem -ComputerName $Computer -ErrorAction Stop
        $mc = Get-WmiObject -class Win32_NetworkAdapterConfiguration -Filter "IPEnabled='True'" -ComputerName $Computer -ErrorAction Stop
        $sr = Get-WmiObject win32_bios -ComputerName $Computer -ErrorAction Stop
        $Xr = Get-WmiObject –class Win32_processor -ComputerName $Computer -ErrorAction Stop 
        $ld = Get-ADComputer $Computer -properties Name,Lastlogondate,ipv4Address,enabled,description,DistinguishedName -ErrorAction Stop
        $r = "{0} GB" -f ((Get-WmiObject Win32_PhysicalMemory -ComputerName $Computer -ErrorAction Stop | Measure-Object Capacity  -Sum).Sum / 1GB)
        $x = Get-WmiObject win32_computersystem -ComputerName $Computer -ErrorAction Stop | select @{Name = "Type";Expression = {if (($_.pcsystemtype -eq '2')  )
            {'Laptop'} Else {'Desktop Or Other'}}
        },Manufacturer,@{Name = "Model";Expression = {if (($_.model -eq "$null")  ) {'Virtual'} Else {$_.model}}},username

        ## Output on creation
        $t= New-Object PSObject -Property @{
            SerialNumber              = $sr.serialnumber -replace "-.*"
            Computername              = $ld.name
            IPaddress                 = $ld.ipv4Address
            MACaddress                = $mc.MACAddress
            Enabled                   = $ld.Enabled
            Description               = $ld.description
            OU                        = $ld.DistinguishedName.split(',')[1].split('=')[1] 
            DC                        = $xx.domain
            Type                      = $x.type
            Manufacturer              = $x.Manufacturer
            Model                     = $x.Model
            RAM                       = $R
            ProcessorName             = ($xr.name | Out-String).Trim()
            NumberOfCores             = ($xr.NumberOfCores | Out-String).Trim()
            NumberOfLogicalProcessors = ($xr.NumberOfLogicalProcessors | Out-String).Trim()
            Addresswidth              = ($xr.Addresswidth | Out-String).Trim()
            Operatingsystem           = $in.caption
            InstallDate               = ([WMI] '').ConvertToDateTime($in.installDate)
            LastLogonDate             = $ld.lastlogondate
            LoggedinUser              = $x.username
        }

        # Only do this kind of update if it hasn't failed yet
        $Output += $t
        $desc="$($mc.MACAddress) ( $($sr.serialnumber -replace "-.*") ) $($x.Model) | $((Get-Date).ToString('MM-dd-yyyy'))"
        Set-ADComputer $Computer -Description $desc -verbose
        $Output | select Computername,Enabled,Description,IPaddress,MACaddress,OU,DC,Type,SerialNumber,Manufacturer,Model,RAM,ProcessorName,NumberOfCores,NumberOfLogicalProcessors,Addresswidth,Operatingsystem,InstallDate,LoggedinUser,LastLogonDate | export-csv -Append $file -NoTypeInformation 

    }
    Catch [Exception]
    {
    # Only do this kind of update if it has failed
        $ErrorMessage = $_.Exception.Message
        Add-Content -value "$Computer, $ErrorMessage, skipping to next" $txt
        Set-ADComputer $Computer -Description $ErrorMessage
            continue
    }
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-04
    • 2014-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-28
    • 2019-02-15
    • 2014-11-28
    相关资源
    最近更新 更多