PowerShell Set-ADComputer 描述基于输入



我有一个代码,它通过Active Directory计算机对象运行以收集信息。然后,该信息的一部分将在活动目录描述字段中更新。 我的问题是,当我收到 Exception.Message 时,计算机的 AD 对象仍然使用上次找到的计算机信息进行更新。 我想了解我该如何:

  • 出现异常时更新 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:scriptsreportsAD-Inentory_$((Get-Date).ToString('MM-dd-yyyy')).csv"
$txt="c:scriptsreportsAD-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
}

在此处continue语句文档,在此处查看示例。

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

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

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

## No Need to define these in the foreach loop
# Output file location to be chnaged as needed
$file = "C:scriptsreportsAD-Inentory_$((Get-Date).ToString('MM-dd-yyyy')).csv"
$txt = "c:scriptsreportsAD-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

在查看包含继续语句的建议后,我能够通过以下最终脚本实现我的问题的解决方案:

# Output file location to be changed as needed
$file="C:scriptsreportsAD-Inentory_$((Get-Date).ToString('MM-dd-yyyy')).csv"
$txt="c:scriptsreportsAD-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
}
}
}

最新更新