PowerShell Set-ADComputer描述基于输入

时间:2018-04-19 19:53:54

标签: powershell active-directory system

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

2 个答案:

答案 0 :(得分: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

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

我认为这将解决您的问题并做您想要实现的目标。我在代码中围绕我所做的更改(由##表示)随意提问。

我建议你使用更多描述性的变量名。

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

答案 1 :(得分:0)

在查看包含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
    }
  }
}