PowerShell根据输入设置计算机描述

PowerShell根据输入设置计算机描述,powershell,active-directory,system,Powershell,Active Directory,System,我有一个代码,它通过Active Directory计算机对象来收集信息。然后在Active directory描述字段中更新部分信息。 我的问题是,当我收到异常消息时,计算机的AD对象仍会使用上次找到的计算机信息进行更新。 我想了解如何: 出现异常时更新广告说明。消息 使用填充的系统信息更新广告说明 附件是我正在使用的脚本,但无法确定将两个Set ADComputer语句的输出放在何处 # Getting computers from Active Directory $C

我有一个代码,它通过Active Directory计算机对象来收集信息。然后在Active directory描述字段中更新部分信息。 我的问题是,当我收到异常消息时,计算机的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
    }

它出现问题行为的原因似乎是它捕获了错误,并根据需要设置了描述

但是,它将继续在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
}
继续
语句文档和示例

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

我认为这将解决您的问题,并实现您正在努力实现的目标。我在代码中对我所做的更改(由
##
表示)进行了注释,可以自由提问

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

## 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

在考虑了包含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
    }
  }
}

看起来你的逻辑有点奇怪,如果电脑处于脱机状态,你打算采取什么行动,完全跳过它或更新它的描述?还有一些事情我想说出来,但没有时间。但是,您应该研究使用cim命令而不是wmiobject命令。ar WMI和CIM命令都较新。我看到了您建议的代码更改。我已经合并了这些更改并运行了它。我的发现是:-不得不将{}添加到{continue}-脚本运行良好,但在随机点我得到了ADComputer:服务器返回了以下错误:枚举上下文无效。-当出现错误的计算机对象时,导出csv日志为空白detected@GregoryMotyka这看起来是一个不同的问题,我会从搜索开始,我发现这看起来像是一个关于搜索的广告索引和页面大小的问题。在最初的搜索中,有很多关于这方面的文章,只需查找错误。