New Question
 
 
PRTG Network Monitor

Intuitive to Use.
Easy to manage.

200.000 administrators have chosen PRTG to monitor their network. Find out how you can reduce cost, increase QoS and ease planning, as well.

Free PRTG
Download >>

 

What is this?

This knowledgebase contains questions and answers about PRTG Network Monitor and network monitoring in general. You are invited to get involved by asking and answering questions!

Learn more

 

Top Tags


View all Tags


Powershell Custom Sensor for monitoring AD User lockouts

Votes:

1

Your Vote:

Up

Down

There is a desire to monitor user lockouts in my organization. This thread offers a script that comes close, but isn't quite what we needed, as it monitors all disabled users.

I've taken that script and adjusted it to only look at non-disabled, non-expired, locked out users. I've decided to post it here in its own thread, because the use case is sufficiently different from the original script. The script is generic and should work in any AD environment. Do keep in mind, though, that the server running the sensor needs to have the Active Directory Powershell module installed.

Import-Module ActiveDirectory

$server=Get-ADUser -Filter * -Properties sAMAccountName,DisplayName,LockedOut,LockoutTime,Enabled,AccountExpirationDate | where {$_.lockedout -eq "True" -and $_.enabled -eq "True" -and (($_.AccountExpirationDate -gt (Get-Date) -or ($_.AccountExpirationDate -eq $null)))}

if ($server.count -eq $null -and $server -eq $null){
    $a=0
}
Elseif ($server.count -eq $null -and $server -ne $null){
    $a=1
}
Else
{
    $a=@($server.count)
}
Write-Host "<prtg>"
Write-Host "<result>" 
"<channel>Locked Out Users</channel>" 
"<value>"+ $a +"</value>" 
"</result>"
"<text>" + (($server | select SamAccountName,DisplayName,@{n='LockoutTime';e={[DateTime]::FromFileTime($_.lockouttime)}} | sort LockoutTime -descending | ConvertTo-Csv -NoTypeInformation | select -skip 1 ) -join ", ").replace("""","") + "</text>"
Write-Host "</prtg>"

If anyone spots any issues with the script, or has suggestions for optimization, I'm happy to hear them.

active-directory powershell user-accounts

Created on Sep 20, 2017 10:50:02 AM by  Bdmm (1) 1



Best Answer

Accepted Answer

Votes:

2

Your Vote:

Up

Down

Tested this - and yes you are right.. the correct line would be:

-LT (less than) and a -AND instead of -OR

resulting in this command:

Get-ADUser -Filter {Enabled -eq $True -and PasswordNeverExpires -eq $False -and objectCategory -eq "person" -and objectClass -eq "user"} -Properties sAMAccountName,DisplayName,LockedOut,LockoutTime,Enabled,AccountExpirationDate | where {(($_.AccountExpirationDate -lt (Get-Date) -and ($_.AccountExpirationDate -ne $null)))} 

and here the corrected full script:

Import-Module ActiveDirectory

#you could add - filters, a OU limitation or a server against whom this would be executed.. see Get-ADUser options for more details

#all locked users that aren't disabled or expired
$LockedOutUsers=Get-ADUser -Filter {Enabled -eq $True -and objectCategory -eq "person" -and objectClass -eq "user"} -Properties sAMAccountName,DisplayName,LockedOut,LockoutTime,Enabled,AccountExpirationDate | where {$_.lockedout -eq $True -and (($_.AccountExpirationDate -gt (Get-Date) -or ($_.AccountExpirationDate -eq $null)))} 

#all users that are disabled - this is a manual action in Active Directory
$DisabledUsers=Get-ADUser -Filter {Enabled -eq $False -and objectCategory -eq "person" -and objectClass -eq "user"} -Properties sAMAccountName,DisplayName,LockedOut,LockoutTime,Enabled,AccountExpirationDate

#all users that are not disabled but expired already
$ExpiredUsers=Get-ADUser -Filter {Enabled -eq $True -and PasswordNeverExpires -eq $False -and objectCategory -eq "person" -and objectClass -eq "user"} -Properties sAMAccountName,DisplayName,LockedOut,LockoutTime,Enabled,AccountExpirationDate | where {(($_.AccountExpirationDate -lt (Get-Date) -and ($_.AccountExpirationDate -ne $null)))} 

#users with not expiring passwords and are enabled and not expired
$NotExpiringPWD=Get-ADUser -Filter {Enabled -eq $True -and PasswordNeverExpires -eq $False -and objectCategory -eq "person" -and objectClass -eq "user"} -Properties sAMAccountName,DisplayName,LockedOut,LockoutTime,Enabled,AccountExpirationDate 

If ($LockedOutUsers.count -eq $null -and $LockedOutUsers -eq $null){
    $cntLockedOutUsers=0
}Elseif ($LockedOutUsers.count -eq $null -and $LockedOutUsers -ne $null){
    $cntLockedOutUsers=1
}Else{
    $cntLockedOutUsers=@($LockedOutUsers.count)
}

If ($DisabledUsers.count -eq $null -and $DisabledUsers -eq $null){
    $cntDisabledUsers=0
}Elseif ($DisabledUsers.count -eq $null -and $DisabledUsers -ne $null){
    $cntDisabledUsers=1
}Else{
    $cntDisabledUsers=@($DisabledUsers.count)
}

If ($ExpiredUsers.count -eq $null -and $ExpiredUsers -eq $null){
    $cntExpiredUsers=0
}Elseif ($ExpiredUsers.count -eq $null -and $ExpiredUsers -ne $null){
    $cntExpiredUsers=1
}Else{
    $cntExpiredUsers=@($ExpiredUsers.count)
}

If ($NotExpiringPWD.count -eq $null -and $NotExpiringPWD -eq $null){
    $cntNotExpiringPWD=0
}Elseif ($NotExpiringPWD.count -eq $null -and $NotExpiringPWD -ne $null){
    $cntNotExpiringPWD=1
}Else{
    $cntNotExpiringPWD=@($NotExpiringPWD.count)
}

$XML += "<prtg>"
$XML += "<result>" 
$XML += "<channel>Locked Out Users</channel>" 
$XML += "<value>$cntLockedOutUsers</value>" 
$XML += "</result>"
$XML += "<result>" 
$XML += "<channel>Disabled Users</channel>" 
$XML += "<value>$cntDisabledUsers</value>" 
$XML += "</result>"
$XML += "<result>" 
$XML += "<channel>Expired Users - not disabled</channel>" 
$XML += "<value>$cntExpiredUsers</value>" 
$XML += "</result>"
$XML += "<result>" 
$XML += "<channel>Users with password never expires</channel>" 
$XML += "<value>$cntNotExpiringPWD</value>" 
$XML += "</result>"
$XML += "</prtg>"

Function WriteXmlToScreen ([xml]$xml)
{
    $StringWriter = New-Object System.IO.StringWriter;
    $XmlWriter = New-Object System.Xml.XmlTextWriter $StringWriter;
    $XmlWriter.Formatting = "indented";
    $xml.WriteTo($XmlWriter);
    $XmlWriter.Flush();
    $StringWriter.Flush();
    Write-Output $StringWriter.ToString();
}

WriteXmlToScreen $XML

Thanks for pointing this out - did not realize this mistake...

Regards

Florian Rossmark

www.it-admins.com

Created on Nov 2, 2018 1:48:47 PM by  Florian Rossmark (4,099) 3 2



19 Replies

Votes:

0

Your Vote:

Up

Down

Hello Bdmm,

Thank you very much for your valuable input, I'm pretty sure that there are users out there who will benefit from your script.

Best regards and thanks again.
Sebastian

Created on Sep 21, 2017 10:33:09 AM by  Sebastian Kniege [Paessler Support]



Votes:

0

Your Vote:

Up

Down

Is it possible to monitor user account lockout status where the sensor is running on a different domain ?

Created on Mar 12, 2018 9:06:12 PM by  gbuelna (0)



Votes:

0

Your Vote:

Up

Down

Tested, works smooth as I have one user locked out and I can see the details in de settings. The counters says 0, so it needs a minor tweak to show 1 ? If users locked out >1, does this sensor show the number of locks, but without the details ??

Created on Mar 16, 2018 4:13:46 PM by  CoDesk (100) 1 1



Votes:

0

Your Vote:

Up

Down

Is it possible to monitor user account lockout status where the sensor is running on a different domain ?

possible yes, but does anybody have a solution to get the Data without the use of a Domain Admin ? Wen don't wan't to use any Domain Admins - instead we use local admins (when necessary and possible)

Created on Apr 17, 2018 2:37:19 PM by  Philipp (222) 1 1



Votes:

0

Your Vote:

Up

Down

This should actually work with a regular user account - any domain user can gather information like this.

What you might need is the RSAT tools installed on the probe-device, besides that I do not see a reason why you shouldn't be able to execute this as a regular user.

Actually, you would be quite surprised seeing what a regular user account can read from your Active Directory. Please have a look at my free IT-Admins Tool at https://www.it-admins.com - you might be quite astonished.

Having this said - I would re-write the script and do it differently and a bit more extended.

The following script will read through your current Active Directory and filter for user accounts with the following specific conditions:

  • Lockedout users - please read below
    • all users that are lockedout
    • must be an enabled user
    • that is not expired
  • disabled users
    • all users that have been disabled
  • expired users
    • must be an enabled user
    • the expiration date is set and past the current date
  • users with password never expires set
    • must be an enabled user

This will give you a pure counter output per channel in an for PRTG Extended script sensor XML result.

But there is a theoretical flaw in one of the methods - the locked out users. Now, user accounts get locked out in Active Directory due to too many logon attempts with an invalid password. This causes Active Directory to set the lockedout bit in the object properties. The issue here is that this bit will not be set back to 0 after the defined lockout duration (GPO) is past, the property will only be set back to 0 once the lockout duration is passed and he successfully logged on.

This means, the counter might give you more results then currently true, it might count users that have been locked out but the lockout-duration passed - but they did not yet logon successfully. This is somehow a false positive, while not totally false. In any case, you need to be aware of this.

The script could be more efficient as well in the way it filters a few things, so far I optimized it as far as I could - the LockedOut value can not be set as a -Filter, in theory it might be possible to speed it up with a -Filter to the UserAccountControl - but I am not certain this would work. If you really want to speed it up you would need to work with -LDAPFilter - but this actually needs to completely replace the internal filter capabilities of Get-ADUser - you can't use both - it is one or the other.

Import-Module ActiveDirectory

#you could add - filters, a OU limitation or a server against whom this would be executed.. see Get-ADUser options for more details

#all locked users that aren't disabled or expired
$LockedOutUsers=Get-ADUser -Filter {Enabled -eq $True -and objectCategory -eq "person" -and objectClass -eq "user"} -Properties sAMAccountName,DisplayName,LockedOut,LockoutTime,Enabled,AccountExpirationDate | where {$_.lockedout -eq $True -and (($_.AccountExpirationDate -gt (Get-Date) -or ($_.AccountExpirationDate -eq $null)))} 

#all users that are disabled - this is a manual action in Active Directory
$DisabledUsers=Get-ADUser -Filter {Enabled -eq $False -and objectCategory -eq "person" -and objectClass -eq "user"} -Properties sAMAccountName,DisplayName,LockedOut,LockoutTime,Enabled,AccountExpirationDate

#all users that are not disabled but expired already
$ExpiredUsers=Get-ADUser -Filter {Enabled -eq $True -and PasswordNeverExpires -eq $False -and objectCategory -eq "person" -and objectClass -eq "user"} -Properties sAMAccountName,DisplayName,LockedOut,LockoutTime,Enabled,AccountExpirationDate | where {(($_.AccountExpirationDate -gt (Get-Date) -or ($_.AccountExpirationDate -ne $null)))} 

#users with not expiring passwords and are enabled and not expired
$NotExpiringPWD=Get-ADUser -Filter {Enabled -eq $True -and PasswordNeverExpires -eq $False -and objectCategory -eq "person" -and objectClass -eq "user"} -Properties sAMAccountName,DisplayName,LockedOut,LockoutTime,Enabled,AccountExpirationDate 

If ($LockedOutUsers.count -eq $null -and $LockedOutUsers -eq $null){
    $cntLockedOutUsers=0
}Elseif ($LockedOutUsers.count -eq $null -and $LockedOutUsers -ne $null){
    $cntLockedOutUsers=1
}Else{
    $cntLockedOutUsers=@($LockedOutUsers.count)
}

If ($DisabledUsers.count -eq $null -and $DisabledUsers -eq $null){
    $cntDisabledUsers=0
}Elseif ($DisabledUsers.count -eq $null -and $DisabledUsers -ne $null){
    $cntDisabledUsers=1
}Else{
    $cntDisabledUsers=@($DisabledUsers.count)
}

If ($ExpiredUsers.count -eq $null -and $ExpiredUsers -eq $null){
    $cntExpiredUsers=0
}Elseif ($ExpiredUsers.count -eq $null -and $ExpiredUsers -ne $null){
    $cntExpiredUsers=1
}Else{
    $cntExpiredUsers=@($ExpiredUsers.count)
}

If ($NotExpiringPWD.count -eq $null -and $NotExpiringPWD -eq $null){
    $cntNotExpiringPWD=0
}Elseif ($NotExpiringPWD.count -eq $null -and $NotExpiringPWD -ne $null){
    $cntNotExpiringPWD=1
}Else{
    $cntNotExpiringPWD=@($NotExpiringPWD.count)
}

$XML += "<prtg>"
$XML += "<result>" 
$XML += "<channel>Locked Out Users</channel>" 
$XML += "<value>$cntLockedOutUsers</value>" 
$XML += "</result>"
$XML += "<result>" 
$XML += "<channel>Disabled Users</channel>" 
$XML += "<value>$cntDisabledUsers</value>" 
$XML += "</result>"
$XML += "<result>" 
$XML += "<channel>Expired Users - not disabled</channel>" 
$XML += "<value>$cntExpiredUsers</value>" 
$XML += "</result>"
$XML += "<result>" 
$XML += "<channel>Users with password never expires</channel>" 
$XML += "<value>$cntNotExpiringPWD</value>" 
$XML += "</result>"
$XML += "</prtg>"

Function WriteXmlToScreen ([xml]$xml)
{
    $StringWriter = New-Object System.IO.StringWriter;
    $XmlWriter = New-Object System.Xml.XmlTextWriter $StringWriter;
    $XmlWriter.Formatting = "indented";
    $xml.WriteTo($XmlWriter);
    $XmlWriter.Flush();
    $StringWriter.Flush();
    Write-Output $StringWriter.ToString();
}

WriteXmlToScreen $XML

The above script was as well posted on my blog here.

Regards

Florian Rossmark

www.it-admins.com

Created on Jul 19, 2018 3:36:16 PM by  Florian Rossmark (4,099) 3 2



Votes:

0

Your Vote:

Up

Down

For correct value display when only 1 account is locked you can replace this :

if ($server.count -eq $null -and $server -eq $null){
    $a=0
}
Elseif ($server.count -eq $null -and $server -ne $null){
    $a=1
}
Else
{
    $a=@($server.count)
}

by this :

$server | ForEach-Object {$a++}

Created on Aug 31, 2018 12:02:12 PM by  PO (0) 1

Last change on Aug 31, 2018 12:53:08 PM by  Sebastian Kniege [Paessler Support]



Votes:

0

Your Vote:

Up

Down

Thanks for that script, looking good so far. However, I fear there's an issue with "Expired Users - not disabled". I can imagine this is down to "Get-Date". It also matches users with an expiry date in the future which obviously is wrong. Adding a "-Format "dd.MM.yyyy HH:mm"" also returns the list containing too many users. Any idea?

Created on Nov 2, 2018 9:27:59 AM by  bezibaerchen (0) 1



Accepted Answer

Votes:

2

Your Vote:

Up

Down

Tested this - and yes you are right.. the correct line would be:

-LT (less than) and a -AND instead of -OR

resulting in this command:

Get-ADUser -Filter {Enabled -eq $True -and PasswordNeverExpires -eq $False -and objectCategory -eq "person" -and objectClass -eq "user"} -Properties sAMAccountName,DisplayName,LockedOut,LockoutTime,Enabled,AccountExpirationDate | where {(($_.AccountExpirationDate -lt (Get-Date) -and ($_.AccountExpirationDate -ne $null)))} 

and here the corrected full script:

Import-Module ActiveDirectory

#you could add - filters, a OU limitation or a server against whom this would be executed.. see Get-ADUser options for more details

#all locked users that aren't disabled or expired
$LockedOutUsers=Get-ADUser -Filter {Enabled -eq $True -and objectCategory -eq "person" -and objectClass -eq "user"} -Properties sAMAccountName,DisplayName,LockedOut,LockoutTime,Enabled,AccountExpirationDate | where {$_.lockedout -eq $True -and (($_.AccountExpirationDate -gt (Get-Date) -or ($_.AccountExpirationDate -eq $null)))} 

#all users that are disabled - this is a manual action in Active Directory
$DisabledUsers=Get-ADUser -Filter {Enabled -eq $False -and objectCategory -eq "person" -and objectClass -eq "user"} -Properties sAMAccountName,DisplayName,LockedOut,LockoutTime,Enabled,AccountExpirationDate

#all users that are not disabled but expired already
$ExpiredUsers=Get-ADUser -Filter {Enabled -eq $True -and PasswordNeverExpires -eq $False -and objectCategory -eq "person" -and objectClass -eq "user"} -Properties sAMAccountName,DisplayName,LockedOut,LockoutTime,Enabled,AccountExpirationDate | where {(($_.AccountExpirationDate -lt (Get-Date) -and ($_.AccountExpirationDate -ne $null)))} 

#users with not expiring passwords and are enabled and not expired
$NotExpiringPWD=Get-ADUser -Filter {Enabled -eq $True -and PasswordNeverExpires -eq $False -and objectCategory -eq "person" -and objectClass -eq "user"} -Properties sAMAccountName,DisplayName,LockedOut,LockoutTime,Enabled,AccountExpirationDate 

If ($LockedOutUsers.count -eq $null -and $LockedOutUsers -eq $null){
    $cntLockedOutUsers=0
}Elseif ($LockedOutUsers.count -eq $null -and $LockedOutUsers -ne $null){
    $cntLockedOutUsers=1
}Else{
    $cntLockedOutUsers=@($LockedOutUsers.count)
}

If ($DisabledUsers.count -eq $null -and $DisabledUsers -eq $null){
    $cntDisabledUsers=0
}Elseif ($DisabledUsers.count -eq $null -and $DisabledUsers -ne $null){
    $cntDisabledUsers=1
}Else{
    $cntDisabledUsers=@($DisabledUsers.count)
}

If ($ExpiredUsers.count -eq $null -and $ExpiredUsers -eq $null){
    $cntExpiredUsers=0
}Elseif ($ExpiredUsers.count -eq $null -and $ExpiredUsers -ne $null){
    $cntExpiredUsers=1
}Else{
    $cntExpiredUsers=@($ExpiredUsers.count)
}

If ($NotExpiringPWD.count -eq $null -and $NotExpiringPWD -eq $null){
    $cntNotExpiringPWD=0
}Elseif ($NotExpiringPWD.count -eq $null -and $NotExpiringPWD -ne $null){
    $cntNotExpiringPWD=1
}Else{
    $cntNotExpiringPWD=@($NotExpiringPWD.count)
}

$XML += "<prtg>"
$XML += "<result>" 
$XML += "<channel>Locked Out Users</channel>" 
$XML += "<value>$cntLockedOutUsers</value>" 
$XML += "</result>"
$XML += "<result>" 
$XML += "<channel>Disabled Users</channel>" 
$XML += "<value>$cntDisabledUsers</value>" 
$XML += "</result>"
$XML += "<result>" 
$XML += "<channel>Expired Users - not disabled</channel>" 
$XML += "<value>$cntExpiredUsers</value>" 
$XML += "</result>"
$XML += "<result>" 
$XML += "<channel>Users with password never expires</channel>" 
$XML += "<value>$cntNotExpiringPWD</value>" 
$XML += "</result>"
$XML += "</prtg>"

Function WriteXmlToScreen ([xml]$xml)
{
    $StringWriter = New-Object System.IO.StringWriter;
    $XmlWriter = New-Object System.Xml.XmlTextWriter $StringWriter;
    $XmlWriter.Formatting = "indented";
    $xml.WriteTo($XmlWriter);
    $XmlWriter.Flush();
    $StringWriter.Flush();
    Write-Output $StringWriter.ToString();
}

WriteXmlToScreen $XML

Thanks for pointing this out - did not realize this mistake...

Regards

Florian Rossmark

www.it-admins.com

Created on Nov 2, 2018 1:48:47 PM by  Florian Rossmark (4,099) 3 2



Votes:

0

Your Vote:

Up

Down

You're welcome :)

Always happy to give back. Thanks a bunch to you for coming up with that. Saved time to self-develop.

Created on Nov 2, 2018 1:57:52 PM by  bezibaerchen (0) 1



Votes:

0

Your Vote:

Up

Down

Hi, where and how can I set a specific OU? I locked out one user for a test but the script shows 0 locked out users. I think the script is looking in the wrong OU.

Created on Nov 12, 2018 10:08:37 AM by  AndreB (0)



Votes:

0

Your Vote:

Up

Down

Script doesn't cehck for a specific OU.

Bear in mind that lock out status needs to be synced between DCs so at the point of time you ran the script, it might either be not synced yet or account may have already unlock again, depending on your domain settings.

Created on Nov 12, 2018 10:15:26 AM by  bezibaerchen (0) 1



Votes:

0

Your Vote:

Up

Down

Hi,

the output of this script showed many (really many) users for the channel "Users with password never expires". I thought that this could not be true. Having a closer look at the script I saw this:

#users with not expiring passwords and are enabled and not expired
$NotExpiringPWD=Get-ADUser -Filter {Enabled -eq $True -and PasswordNeverExpires -eq $False -and objectCategory -eq "person" -and objectClass -eq "user"} -Properties sAMAccountName,DisplayName,LockedOut,LockoutTime,Enabled,AccountExpirationDate

Shouldn't it be PasswordNeverExpires -eq $True ?

Created on Feb 7, 2019 12:58:26 PM by  puthz (0)



Votes:

1

Your Vote:

Up

Down

Good catch... it is a while that I played around with that script.. interestingly no one ever complained, lol...

You can easily run those commands manually and compare the output to Active Directory manually..

In theory there is more that should be adjusted here... cause the $ExpiredUsers filters for Password never expires $false as well.. so this would be a more updated version of the script

Additionally I added a few notes about how to filter OUs and execute it on a specific server.. in theory the whole script could be changed so it accepts parameter and does everything more variable.. but that's for another day..

Import-Module ActiveDirectory

#you could add - filters, a OU limitation or a server against whom this would be executed.. see Get-ADUser options for more details
#$Server = ""
#$OU = ""
#Get-ADUser -Server $Server -Filter
#Get-ADUser -SearchBase $OU -Filter

#all locked users that aren't disabled or expired
$LockedOutUsers=Get-ADUser -Filter {Enabled -eq $True -and objectCategory -eq "person" -and objectClass -eq "user"} -Properties sAMAccountName,DisplayName,LockedOut,LockoutTime,Enabled,AccountExpirationDate | where {$_.lockedout -eq $True -and (($_.AccountExpirationDate -gt (Get-Date) -or ($_.AccountExpirationDate -eq $null)))} 

#all users that are disabled - this is a manual action in Active Directory
$DisabledUsers=Get-ADUser -Filter {Enabled -eq $False -and objectCategory -eq "person" -and objectClass -eq "user"} -Properties sAMAccountName,DisplayName,LockedOut,LockoutTime,Enabled,AccountExpirationDate

#all users that are not disabled but expired already
$ExpiredUsers=Get-ADUser -Filter {Enabled -eq $True -and objectCategory -eq "person" -and objectClass -eq "user"} -Properties sAMAccountName,DisplayName,LockedOut,LockoutTime,Enabled,AccountExpirationDate | where {(($_.AccountExpirationDate -lt (Get-Date) -and ($_.AccountExpirationDate -ne $null)))} 

#users with not expiring passwords and are enabled and not expired
$NotExpiringPWD=Get-ADUser -Filter {Enabled -eq $True -and PasswordNeverExpires -eq $True -and objectCategory -eq "person" -and objectClass -eq "user"} -Properties sAMAccountName,DisplayName,LockedOut,LockoutTime,Enabled,AccountExpirationDate 


If ($LockedOutUsers.count -eq $null -and $LockedOutUsers -eq $null){
    $cntLockedOutUsers=0
}Elseif ($LockedOutUsers.count -eq $null -and $LockedOutUsers -ne $null){
    $cntLockedOutUsers=1
}Else{
    $cntLockedOutUsers=@($LockedOutUsers.count)
}

If ($DisabledUsers.count -eq $null -and $DisabledUsers -eq $null){
    $cntDisabledUsers=0
}Elseif ($DisabledUsers.count -eq $null -and $DisabledUsers -ne $null){
    $cntDisabledUsers=1
}Else{
    $cntDisabledUsers=@($DisabledUsers.count)
}

If ($ExpiredUsers.count -eq $null -and $ExpiredUsers -eq $null){
    $cntExpiredUsers=0
}Elseif ($ExpiredUsers.count -eq $null -and $ExpiredUsers -ne $null){
    $cntExpiredUsers=1
}Else{
    $cntExpiredUsers=@($ExpiredUsers.count)
}

If ($NotExpiringPWD.count -eq $null -and $NotExpiringPWD -eq $null){
    $cntNotExpiringPWD=0
}Elseif ($NotExpiringPWD.count -eq $null -and $NotExpiringPWD -ne $null){
    $cntNotExpiringPWD=1
}Else{
    $cntNotExpiringPWD=@($NotExpiringPWD.count)
}

$XML += "<prtg>"
$XML += "<result>" 
$XML += "<channel>Locked Out Users</channel>" 
$XML += "<value>$cntLockedOutUsers</value>" 
$XML += "</result>"
$XML += "<result>" 
$XML += "<channel>Disabled Users</channel>" 
$XML += "<value>$cntDisabledUsers</value>" 
$XML += "</result>"
$XML += "<result>" 
$XML += "<channel>Expired Users - not disabled</channel>" 
$XML += "<value>$cntExpiredUsers</value>" 
$XML += "</result>"
$XML += "<result>" 
$XML += "<channel>Users with password never expires</channel>" 
$XML += "<value>$cntNotExpiringPWD</value>" 
$XML += "</result>"
$XML += "</prtg>"

Function WriteXmlToScreen ([xml]$xml)
{
    $StringWriter = New-Object System.IO.StringWriter;
    $XmlWriter = New-Object System.Xml.XmlTextWriter $StringWriter;
    $XmlWriter.Formatting = "indented";
    $xml.WriteTo($XmlWriter);
    $XmlWriter.Flush();
    $StringWriter.Flush();
    Write-Output $StringWriter.ToString();
}

WriteXmlToScreen $XML

Created on Feb 7, 2019 2:49:06 PM by  Florian Rossmark (4,099) 3 2



Votes:

0

Your Vote:

Up

Down

Hi,

I am trying to use the above script (PRTG v.18.4.46.1754) but i'm getting the below error:

XML: The returned XML does not match the expected schema. (code: PE233) -- JSON: The returned JSON does not match the expected structure (Invalid JSON.). (code: PE231)

Any ideas?

Created on Feb 12, 2019 9:38:34 PM by  lzsembera (0)



Votes:

0

Your Vote:

Up

Down

Dear lzsembera,

in order to debug this, please open the Settings tab of the sensor and enable "Write Exe result to disk".

After the next scans, the logs appear in "C:\ProgramData\Paessler\PRTG Network Monitor\Logs (Sensors)".

If you look at the Powershell output included in the log, do you see the cause of the script execution error?

Created on Feb 12, 2019 10:58:16 PM by  Arne Seifert [Paessler Support]



Votes:

0

Your Vote:

Up

Down

Hi I have implemented this script, but even in a Powershell ISE session it errors when it comes to writing out the results:-

WriteXmlToScreen : Cannot process argument transformation on parameter 'xml'. Cannot convert value "<prtg><result><channel>Locked Out Users</channel><value>0</value></result><result><channel>Disabled Users</channel><value>0</value></result><result><channel>Expired Users - not disabled</channel><value>0</value></result><result><channel>Users with password never expires</channel><value>0</value></result></prtg><prtg><result><channel>Locked Out Users</channel><value>0</value></result><result><channel>Disabled Users</channel><value>558</value></result><result><channel>Expired Users - not disabled</channel><value>3</value></result><result><channel>Users with password never expires</channel><value>408</value></result></prtg><prtg><result><channel>Locked Out Users</channel><value>0</value></result><result><channel>Disabled Users</channel><value>558</value></result><result><channel>Expired Users - not disabled</channel><value>3</value></result><result><channel>Users with password never expires</channel><value>408</value></result></prtg><prtg><result><channel>Locked Out Users</channel><value>0</value></result><result><channel>Disabled Users</channel><value>558</value></result><result><channel>Expired Users - not disabled</channel><value>3</value></result><result><channel>Users with password never expires</channel><value>408</value></result></prtg>" to type "System.Xml.XmlDocument". Error: "This document already has a 'DocumentElement' node." At line:84 char:18 + WriteXmlToScreen $XML + ~~~~ + CategoryInfo : InvalidData: (:) [WriteXmlToScreen], ParameterBindingArgumentTransformationException + FullyQualifiedErrorId : ParameterArgumentTransformationError,WriteXmlToScreen

Any guidance?

Created on Feb 19, 2019 4:07:42 PM by  Ian Noble (0)

Last change on Feb 20, 2019 5:19:22 AM by  Sven Roggenhofer [Paessler Technical Support]



Votes:

0

Your Vote:

Up

Down

Hi Ian,

The XML data posted from you looks like this:

<prtg>
<result><channel>Locked Out Users</channel><value>0</value></result>
<result><channel>Disabled Users</channel><value>0</value></result>
<result><channel>Expired Users - not disabled</channel><value>0</value></result>
<result><channel>Users with password never expires</channel><value>0</value></result>
</prtg>

<prtg>
<result><channel>Locked Out Users</channel><value>0</value></result>
<result><channel>Disabled Users</channel><value>558</value></result>
<result><channel>Expired Users - not disabled</channel><value>3</value></result>
<result><channel>Users with password never expires</channel><value>408</value></result>
</prtg>

<prtg>
<result><channel>Locked Out Users</channel><value>0</value></result>
<result><channel>Disabled Users</channel><value>558</value></result>
<result><channel>Expired Users - not disabled</channel><value>3</value></result>
<result><channel>Users with password never expires</channel><value>408</value></result>
</prtg>

<prtg>
<result><channel>Locked Out Users</channel><value>0</value></result>
<result><channel>Disabled Users</channel><value>558</value></result>
<result><channel>Expired Users - not disabled</channel><value>3</value></result>
<result><channel>Users with password never expires</channel><value>408</value></result>
</prtg>

Did you modify the script? I don't see any reason that the output would a) put in to the $XML value 4x times nor that you would have all 0s in the first XML Element group...

Florian

Created on Feb 20, 2019 2:53:46 PM by  Florian Rossmark (4,099) 3 2



Votes:

0

Your Vote:

Up

Down

Forgive my ignorance, how do i install this?

Created on Apr 9, 2019 10:46:54 AM by  chi_ltd1 (0)



Votes:

0

Your Vote:

Up

Down

Copy the script to EXEXML folder, restart Probe/Core then you can select it for custom script monitoring

Created on Apr 9, 2019 10:51:37 AM by  bezibaerchen (0) 1



Please log in or register to enter your reply.


Disclaimer: The information in the Paessler Knowledge Base comes without warranty of any kind. Use at your own risk. Before applying any instructions please exercise proper system administrator housekeeping. You must make sure that a proper backup of all your data is available.