Powershell script to update the computer description with the machine last contacted days and no of Hrs online.

bsharath
bsharath used Ask the Experts™
on
Hi,

Powershell script to update the computer description with the machine last contacted days and no of Hrs online.
Script to update the details as
 
(Contacts  : 8  days) (Online : 12 hrs)

Regards
sharath
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Chris DentPowerShell Developer
Top Expert 2010

Commented:

You're not going to get the "Online" part I'm afraid. Nothing in AD records that kind of information.

Contacts is tricky because the most accurate metric, lastLogon, is not replicated which means any script would have to check every DC in the domain.

Chirs

Author

Commented:
Thanks Chris
I have 4 Dc's in this specific Domain. I can mention those dc names if needed
And
for the online status the script has to query each machine and check for the uptime and record the description.
Chris DentPowerShell Developer
Top Expert 2010

Commented:

In theory although I can't test it here.

As with the other script, the OU its looking at is defined by SearchRoot on line 3.

Unless you want something else for Contact?

Chris
$Computers = @{}
Get-QADComputer -ComputerRole DomainController | ForEach-Object {
  Get-QADComputer -SearchRoot "domain.com/Offices" -Service $_.Name -SizeLimit 0 -IncludedProperties LastLogon | `
    Select-Object Name, DN, LastLogon | ForEach-Object { 
      If ($Computers.$($_.DN)) {
        $Computers.$($_.DN) = $_ | Select-Object Name, DN, `
          @{n='LastLogon';e={ 
            If ($_.LastLogon -gt $Computers.$($_.DN).LastLogon) { 
              $_.LastLogon 
            } Else { 
              $Computers.$($_.DN).LastLogon 
            } }}
      } Else {
        $Computers.Add($_.DN, $_)
      }
    }
}

$Computers.Values | ForEach-Object {
  $LastLogon = (New-TimeSpan $_.LastLogon).Days
  $Online = (New-TimeSpan $([Management.ManagementDateTimeConverter]::ToDateTime((Get-WmiObject Win32_OperatingSystem -Computer $_.Name).LastBootUpTime))).Hours

  Set-QADComputer $_.DN -Description "(Contacts: $LastLogon days) (Online: $Online hours)"
}

Open in new window

JavaScript Best Practices

Save hours in development time and avoid common mistakes by learning the best practices to use for JavaScript.

Author

Commented:
I get this

Get-QADComputer : Cannot resolve directory object for the given identity: 'lth.local/Migrated Mail &  AD Users'.
At line:2 char:18
+   Get-QADComputer <<<<  -SearchRoot "lth.local/Migrated Mail &  AD Users " -Service $_.Name -SizeLimit 0 -IncludedProperties LastLogon | `
    + CategoryInfo          : NotSpecified: (:) [Get-QADComputer], ObjectNotFoundException
    + FullyQualifiedErrorId : Quest.ActiveRoles.ArsPowerShellSnapIn.DirectoryAccess.ObjectNotFoundException,Quest.Acti
   veRoles.ArsPowerShellSnapIn.Powershell.Cmdlets.GetComputerCmdlet
Chris DentPowerShell Developer
Top Expert 2010

Commented:

You have two spaces in the path (between & and AD), "Migrated Mail &  AD Users", is that intentional?

Anyway, it's erroring because of your path, although I'd be surprised if the thing worked first time I can't fix that one for you.

Chris

Author

Commented:
Ok got it its reading. Will it scan all Dc's no matter what site?
Total i have 100's of dc's in all sites togeather.
Can we not limit it to 1 site as it takes a long time
For some dc's that are removed it errors.
So can we fix it to 4 dc's on my site
Chris DentPowerShell Developer
Top Expert 2010

Commented:

> Ok got it its reading. Will it scan all Dc's no matter what site?

Yes.

It can be limited, but such a limitation reduces the accuracy of the data.

Anyway, this allows you to hard-code the Domain Controllers.

Chris
$DomainControllers = "dc1", "dc2", "dc3", "dc4"

$Computers = @{}
$DomainControllers | ForEach-Object {
  Get-QADComputer -SearchRoot "domain.com/Offices" -Service $_ -SizeLimit 0 -IncludedProperties LastLogon | `
    Select-Object Name, DN, LastLogon | ForEach-Object { 
      If ($Computers.$($_.DN)) {
        $Computers.$($_.DN) = $_ | Select-Object Name, DN, `
          @{n='LastLogon';e={ 
            If ($_.LastLogon -gt $Computers.$($_.DN).LastLogon) { 
              $_.LastLogon 
            } Else { 
              $Computers.$($_.DN).LastLogon 
            } }}
      } Else {
        $Computers.Add($_.DN, $_)
      }
    }
}

$Computers.Values | ForEach-Object {
  $LastLogon = (New-TimeSpan $_.LastLogon).Days
  $Online = (New-TimeSpan $([Management.ManagementDateTimeConverter]::ToDateTime((Get-WmiObject Win32_OperatingSystem -Computer $_.Name).LastBootUpTime))).Hours

  Set-QADComputer $_.DN -Description "(Contacts: $LastLogon days) (Online: $Online hours)"
}

Open in new window

Author

Commented:
I get this

Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)
At line:3 char:96
+   $Online = (New-TimeSpan $([Management.ManagementDateTimeConverter]::ToDateTime((Get-WmiObject <<<<  Win32_Operating
System -Computer $_.Name).LastBootUpTime))).Hours
    + CategoryInfo          : InvalidOperation: (:) [Get-WmiObject], COMException
    + FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

Exception calling "ToDateTime" with "1" argument(s): "Specified argument was out of the range of valid values.
Parameter name: dmtfDate"
At line:3 char:81
+   $Online = (New-TimeSpan $([Management.ManagementDateTimeConverter]::ToDateTime <<<< ((Get-WmiObject Win32_Operating
System -Computer $_.Name).LastBootUpTime))).Hours
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

New-TimeSpan : Cannot bind parameter 'Start' to the target. Exception setting "Start": "Object reference not set to an
instance of an object."
At line:3 char:26
+   $Online = (New-TimeSpan <<<<  $([Management.ManagementDateTimeConverter]::ToDateTime((Get-WmiObject Win32_Operating
System -Computer $_.Name).LastBootUpTime))).Hours
    + CategoryInfo          : WriteError: (:) [New-TimeSpan], ParameterBindingException
    + FullyQualifiedErrorId : ParameterBindingFailed,Microsoft.PowerShell.Commands.NewTimeSpanCommand
Chris DentPowerShell Developer
Top Expert 2010

Commented:

You're going to get that problem a lot. This might address it in part.

Chris
$DomainControllers = "dc1", "dc2", "dc3", "dc4"

$Computers = @{}
$DomainControllers | ForEach-Object {
  Get-QADComputer -SearchRoot "domain.com/Offices" -Service $_ -SizeLimit 0 -IncludedProperties LastLogon | `
    Select-Object Name, DN, LastLogon | ForEach-Object { 
      If ($Computers.$($_.DN)) {
        $Computers.$($_.DN) = $_ | Select-Object Name, DN, `
          @{n='LastLogon';e={ 
            If ($_.LastLogon -gt $Computers.$($_.DN).LastLogon) { 
              $_.LastLogon 
            } Else { 
              $Computers.$($_.DN).LastLogon 
            } }}
      } Else {
        $Computers.Add($_.DN, $_)
      }
    }
}

$Computers.Values | ForEach-Object {
  $LastLogon = (New-TimeSpan $_.LastLogon).Days

  If (Test-Connection $_.Name -Quiet -Count 1) {
    $LastBootUpTime = (Get-WmiObject Win32_OperatingSystem -Computer $_.Name).LastBootUpTime
    If ($LastBootUpTime -ne $Null) {
      $LastBootUpTime = [Management.ManagementDateTimeConverter]::ToDateTime($LastBootUpTime)

      $Online = (New-TimeSpan $LastBootUpTime).Hours
    }
  } Else {
    $Online = 0
  }

  Set-QADComputer $_.DN -Description "(Contacts: $LastLogon days) (Online: $Online hours)"
}

Open in new window

Author

Commented:
Ok those errors come when the machine is switched orr or if access denied?

For a machine i get data as this

(Contacts: 25 days) (Online: 5 hours)
its not contacted for 25 das but its online for 5 Hrs.
Is this right
Chris DentPowerShell Developer
Top Expert 2010

Commented:

Yes, ping (Test-Connection) should deal with the offline instance, but access denied will still throw.

Regarding Contact, it's possible. For instance, if the computer was switched on before being connected to the network then LastLogon would not be updated. Or it may have logged into a DC outside of the scope you've defined.

Chris

Author

Commented:
Is there a way i can force a contact to DC and then start the scan .
I have mentioned 4 dc's and i am sure they are the onl ones authenticating them
Chris DentPowerShell Developer
Top Expert 2010

Commented:

You could reboot the machine? Not very likely to make you popular though.

Chris

Author

Commented:
The machine online time does not show right
My machine is online for 2 days 10 hrs but in the description it shows 7 hrs
PowerShell Developer
Top Expert 2010
Commented:

Updated.

Chris
$DomainControllers = "dc1", "dc2", "dc3", "dc4"

$Computers = @{}
$DomainControllers | ForEach-Object {
  Get-QADComputer -SearchRoot "domain.com/Offices" -Service $_ -SizeLimit 0 -IncludedProperties LastLogon | `
    Select-Object Name, DN, LastLogon | ForEach-Object { 
      If ($Computers.$($_.DN)) {
        $Computers.$($_.DN) = $_ | Select-Object Name, DN, `
          @{n='LastLogon';e={ 
            If ($_.LastLogon -gt $Computers.$($_.DN).LastLogon) { 
              $_.LastLogon 
            } Else { 
              $Computers.$($_.DN).LastLogon 
            } }}
      } Else {
        $Computers.Add($_.DN, $_)
      }
    }
}

$Computers.Values | ForEach-Object {
  $LastLogon = (New-TimeSpan $_.LastLogon).Days

  If (Test-Connection $_.Name -Quiet -Count 1) {
    $LastBootUpTime = (Get-WmiObject Win32_OperatingSystem -Computer $_.Name).LastBootUpTime
    If ($LastBootUpTime -ne $Null) {
      $LastBootUpTime = [Management.ManagementDateTimeConverter]::ToDateTime($LastBootUpTime)

      $Online = [Math]::Round((New-TimeSpan $LastBootUpTime).TotalHours, 2)
    }
  } Else {
    $Online = 0
  }

  Set-QADComputer $_.DN -Description "(Contacts: $LastLogon days) (Online: $Online hours)"
}

Open in new window

Author

Commented:
Thank you

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial