Reputation: 21
I have a code which runs trough Active Directory computers objects to collect information. Part of that information is then updated on Active directory description field. My problem is that when I get the Exception.Message the AD object of a computer is still updated with the last found computer information. I would like to find out how can I:
Attached is the script I'm using but can't figure out where to put the output for the two Set-ADComputer statements
# 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
}
Upvotes: 2
Views: 3338
Reputation: 21
After looking at the suggestion to include continue statement I was able to achieve the solution to my problem with the following final script:
# 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
}
}
}
Upvotes: 0
Reputation: 2509
It looks like the reason why it had the problem behaviour is it was catching the error, and setting the description as you wanted with the error.
However it would then continue on to evaluate the code outside of the catch and the else block, since it failed on the current computer the variables used to build the description variable still contained data from the previous computer that was successful and then update the failed computer again.
You could fix this by using the continue
statement at the bottom of the catch block to skip the rest of the code for that iteration and move to the next item in the loop.
That solution would look like this:
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
statement documentation here and examples here.
The other option is you restructure your code to make sure this cannot happen, like below.
I think this will fix your issue and do what you are trying to achieve. I put comments in the code around the changes I made (denoted by the ##
) feel free to ask questions.
I would recommend you use more descriptive variable names.
## 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
Upvotes: 1