I have a lot of users in my PRTG and I'd like to see who's logged in the last time. Is this possible?
Article Comments
At the moment, the script doesn´t work. Ich filled the server, username and passhash field, but with the execution I´ve got multiple errors:
Cannot index into a null array. At C:\Users\boet026\Desktop\user.ps1:33 char:5 + $userlist_names += $userlist_names_raw.Groups[$i].Value + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : NullArray
Jan, 2019 - Permalink
Hi Marc,
Please execute the above script again with all variables set, afterwards execute the following command manually and forward us the error you might get:
Invoke-WebRequest -Uri $userlist_url -UseBasicParsing |
Best regards.
Jan, 2019 - Permalink
Hi Dariusz,
here ist my output
Information posted were deleted by the administrators.
Jan, 2019 - Permalink
Hi Marc,
Seems like we have changed the layout of the tables. The regular expressions weren't working for the post-facelift versions. Please see the initial post where I added a facelift-compatible script.
Best regards.
Jan, 2019 - Permalink
Hi Dariusz,
thank you for the new code.
that doesn´t work, I´ve got this error:
Cannot index into a null array.
At C:\Users\boet026\Desktop\user.ps1:33 char:5
+ $userlist_names += $userlist_names_raw.Groups[$i].Value
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArray
Here is the output from
Invoke-WebRequest -Uri $userlist_url -UseBasicParsing
StatusCode : 200
StatusDescription : OK
Content : <div class="contexthelpbox prtg-plugin" data-id="id1809916606" data-plugin="contexthelp" data-plugin-function="add"
data-plugin-target="#header_help" data-show="true"><div class="helpheader">Benutzerk...
RawContent : HTTP/1.1 200 OK
Connection: close
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Content-Length: 41390
Cache-Control: no-cache
Content-Type: text/html; charset=UTF-8
Date: Wed,...
Forms :
Headers : {[Connection, close], [X-Content-Type-Options, nosniff], [X-XSS-Protection, 1; mode=block], [Content-Length, 41390]...}
Images : {}
InputFields : {@{outerHTML=<input id="selectall_2_usertable" title="Alle Einträge auswählen" type="checkbox" class="checkbox tablemultiselectcheckbox
selectallasmultiedit" value="-3"/>; tagName=INPUT; id=selectall_2_usertable; title=Alle Einträge auswählen; type=checkbox; class=checkbox
tablemultiselectcheckbox selectallasmultiedit; value=-3}}
Links : {@{outerHTML=<a href='/help/user_accounts_settings.htm#settings' target='_blank'><b>Help: User Accounts</b></a>; tagName=A;
href=/help/user_accounts_settings.htm#settings; target=_blank}, @{outerHTML=<a class="actionbutton add-menu-item"
href="/edituser.htm?id=new">Benutzer hinzufügen</a>; tagName=A; class=actionbutton add-menu-item; href=/edituser.htm?id=new},
@{outerHTML=<a class="actionbutton add-menu-item" href="#" onclick="_Prtg.Dialogs.addMultipleUserDialog(); return false;">Mehrere Benutzer
hinzufügen</a>; tagName=A; class=actionbutton add-menu-item; href=#; onclick=_Prtg.Dialogs.addMultipleUserDialog(); return false;},
@{outerHTML=<a class="actionbutton add-menu-item" href="/editusergroup.htm?id=new">Benutzergruppe hinzufügen</a>; tagName=A;
class=actionbutton add-menu-item; href=/editusergroup.htm?id=new}...}
ParsedHtml :
RawContentLength : 41390
Jan, 2019 - Permalink
Hi Marc,
Have you use the first code posted above?
If so, please execute it again and issue the following command afterwards:
$userlist = Invoke-WebRequest -Uri $userlist_url -UseBasicParsing $userlist.Content
Please post this result as well. :)
Best regards.
Jan, 2019 - Permalink
Hi, here is my output.
----------------- Please moderate the content, cause of names :)
deleted due to personal data
Jan, 2019 - Permalink
Hi Marc,
I guess I found the issue, your installation uses the German language which is why some fields have other names. Please try the code below and let me know if it works:
#requires -version 4.0 # ___ ___ _____ ___ #| _ \ _ \_ _/ __| #| _/ / | || (_ | #|_| |_|_\ |_| \___| # Last Login of PRTG Users # ================================ # This script will show you when which user logged in the last time. # ---------------------------- # # # # # # # # # # # # # # # # # # # # # # # # # # param( $server = "http://your-prtg", $username = "user", $passhash = 3091222222 ) $userlist_url = $server + "/controls/userlist.htm?count=9000&username=" + $username + "&passhash=" + $passhash $userlist_ids_regex = "<a class=.usermenu. id=.([0-9]+)..href=.edituser.htm.id=[0-9]+.>" $userlist_names_regex = "<td class=.col-name.data-th=.Obje.t.><a class=.usermenu. id=.[0-9]+. href=.edituser.htm.id=[0-9]+.>(.+)<.a>.+<.td><td class=.col-type.data-th=." $userlist = Invoke-WebRequest -Uri $userlist_url -UseBasicParsing $userlist_ids_raw = Select-String $userlist_ids_regex -input $userlist -AllMatches | Foreach {$_.Matches} $userlist_names_raw = Select-String $userlist_names_regex -input $userlist -AllMatches | Foreach {$_.Matches} [string[]]$userlist_ids = $null [string[]]$userlist_names = $null for($i=0; $i -lt $userlist_ids_raw.Groups.Count; $i++){ $i++ $userlist_ids += $userlist_ids_raw.Groups[$i].Value $userlist_names += $userlist_names_raw.Groups[$i].Value } ########################################################################################## $userlogin_regex = "<div class=.readonlyproperty. >(.+)<.div><.div>" $userlogin_uname_regex = '<input class="text".*data-rule-required="true" type="text" name="login." id="login." autocomplete="off" value="(.*)".*><.div>' [string[]]$userlogin_times = $null [string[]]$userlogin_uname = $null for($i=0; $i -lt $userlist_ids.Count; $i++){ $userlogin_url = $server + "/controls/edituser.htm?id=" + $userlist_ids[$i] + "&username=" + $username + "&passhash=" + $passhash $userlogin = Invoke-WebRequest -Uri $userlogin_url -UseBasicParsing $userlogin_times_raw = Select-String $userlogin_regex -input $userlogin -AllMatches | Foreach {$_.Matches} $userlogin_times += $userlogin_times_raw.Groups[1].Value $userlogin_uname_raw = Select-String $userlogin_uname_regex -input $userlogin -AllMatches | Foreach {$_.Matches} $userlogin_uname += $userlogin_uname_raw.Groups[1].Value } $UserList = New-Object System.Collections.ArrayList($null) if($userlist_ids.Count -eq $userlist_names.Count -and $userlist_ids.Count -eq $userlogin_times.Count -and $userlist_names.Count -eq $userlogin_times.Count -and $userlist_names.Count -eq $userlogin_uname.Count){ for($i=0; $i -lt $userlist_ids.Count; $i++){ $User = New-Object -TypeName psobject Add-Member -InputObject $User -Name ID -Value $userlist_ids[$i] -MemberType NoteProperty Add-Member -InputObject $User -Name "User Name" -Value $userlist_names[$i] -MemberType NoteProperty Add-Member -InputObject $User -Name "Login Name" -Value $userlogin_uname[$i] -MemberType NoteProperty Add-Member -InputObject $User -Name "Last Login" -Value $userlogin_times[$i] -MemberType NoteProperty $UserList.add($User) | Out-Null } } $UserList | Out-GridView -Title "[PRTG] Last Login of all Users"
Jan, 2019 - Permalink
Hallo, danke für Schript. Script liefert keine date. Startet, Endet ohne Fehlel, liefert leider keine Daten. Was kann das sein?
Jan, 2019 - Permalink
Hallo Herr Koifman,
Welches der beiden obigen Scripte haben Sie verwendet? Welche Interface-Sprache ist bei Ihnen eingestellt und am wichtigsten, welche Version setzen Sie ein?
Best regards.
Jan, 2019 - Permalink
Hallo Dariusz, wir verwenden Version DE V18.4.46.1754. Und ich habe alle vorgeschlagene Scripte probiert. Letzte Script extra für DE Interface liefert auch keine Ergebnisse. Danke
Jan, 2019 - Permalink
Hallo Herr Koifman,
Erhalten Sie denn einen Fehler beim ausführen? Die Parameter haben Sie vor der Ausführung auch angepasst?
Best regards
Jan, 2019 - Permalink
Hi
I recieve this error:
Invoke-WebRequest : The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. At line:22 char:13 + $userlist = Invoke-WebRequest -Uri $userlist_url -UseBasicParsing + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
I think it is because my prtg uses HTTPS
any idea how to fix this?
Thanks!
Feb, 2019 - Permalink
Hi there,
Please add the following to the beginning of the script, afterwards it should work fine:
if (-not ([System.Management.Automation.PSTypeName]'ServerCertificateValidationCallback').Type) { $certCallback = @" using System; using System.Net; using System.Net.Security; using System.Security.Cryptography.X509Certificates; public class ServerCertificateValidationCallback { public static void Ignore() { if(ServicePointManager.ServerCertificateValidationCallback ==null) { ServicePointManager.ServerCertificateValidationCallback += delegate ( Object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors ) { return true; }; } } } "@ Add-Type $certCallback } [ServerCertificateValidationCallback]::Ignore()
Best regards!
Feb, 2019 - Permalink
Hello,
I'm still getting the Error
Es ist nicht möglich, einen Index auf ein NULL-Array anzuwenden.
In C:\Users\mak\Desktop\Code\PRTG_User_inactiv.ps1:25 Zeichen:5
+ $userlist_names += $userlist_names_raw.Groups[$i].Value
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArray
PRTG Version is 19.4.53.1912+ and language is German
A Get-Variable after the script shows (data anonymised)
userlist {}
userlist_ids {98811, 134833, 96379, 16808...}
userlist_ids_raw {0, 0, 0, 0...}
userlist_ids_regex <a class=.usermenu. id=.([0-9]+)..href=.edituser.htm.id=[0-9]+.>
userlist_names
userlist_names_raw
userlist_names_regex <td class=.col-name.data-th=.Obje.t.><a class=.usermenu. id=.[0-9]+. href=.edituser.htm.id=[0-9]+.>(.+)<.a>.+<.td><td class=.col-type.d...
userlist_url https://MYDOMAIN.local/controls/userlist.htm?count=9000&username=admin123&passhash=123456789
userlogin <form id="edituserform" action="/editsettings" method="post" class="prtg-form prtg-plugin" data-plugin="prtg-form" data-ajaxsubmit="tru...
userlogin_regex <div class=.readonlyproperty. >(.+)<.div><.div>
userlogin_times {8/24/2017 8:54:42 AM, 10/2/2018 9:38:19 AM, 6/13/2017 2:06:36 PM, 3/1/2017 4:18:13 PM...}
userlogin_times_raw <div class="readonlyproperty" >(hat sich bislang nicht angemeldet)</div></div>
userlogin_uname {user1, user2, user3, use...}
userlogin_uname_raw <input class="text" data-rule-required="true" type="text" name="login_" id="login_" autocomplete="off" value="USER.USER@Compan...
userlogin_uname_regex <input class="text".*data-rule-required="true" type="text" name="login." id="login." autocomplete="off" value="(.*)".*><.div>
userlogin_url https://MYDOMAIN.local/controls/edituser.htm?id=111786&username=admin123&passhash=123456789
username admin123
I get the same error with all 3 scripts posted here.
$userlist = Invoke-WebRequest -Uri $userlist_url -UseBasicParsing
$userlist.Content
Works and shows all Users
Invoke-WebRequest -Uri $userlist_url -UseBasicParsing
gives the same results as in Marcs earlier Post.
Any help is highly appreciated, thanks in advance
Marcel
Nov, 2019 - Permalink
@Marcel_K
Thanks for the issue report. I've fixed the script accordingly and modified some of the regular expressions. It's now working properly with HTTPS connections as well as the latest version of PRTG.
Let me know if it worked!
Nov, 2019 - Permalink
I'm trying this script on our PRTG server version 20.4.63.1427+ and it is not working.
I get the following error:
At C:\Users\XuserX\Desktop\lastlogin.ps1:44 char:15
+ $server = "https://X.X.X.X",
+ ~~~~~~~~~~~~~~~~~~~~~
The assignment expression is not valid. The input to an assignment operator must be an object that is able to accept
assignments, such as a variable or a property.
At C:\Users\XuserX\Desktop\lastlogin.ps1:45 char:17
+ $username = "XuserX",
+ ~~~~~~~~
The assignment expression is not valid. The input to an assignment operator must be an object that is able to accept
assignments, such as a variable or a property.
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : InvalidLeftHandSide
The server and user were changed for this post.
Dec, 2020 - Permalink
Any special characters in the group of the user it might fail for? Paste the following as line 44 below i++;:
Write-Host "User: $($userlist_names_raw.Groups[$i].Value) (#$($userlist_ids_raw.Groups[$i].Value))"
...to see where it actually fails.
Dec, 2020 - Permalink
after adding this line and re-running the script, I get the error below
At C:\Users\XuserX\Desktop\lastlogin.ps1:44 char:101
+ ... ps[$i].Value))"
+ ~
Missing closing ')' in expression.
At C:\Users\XuserX\Desktop\lastlogin.ps1:48 char:1
+ )
+ ~
Unexpected token ')' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : MissingEndParenthesisInExpression
Dec, 2020 - Permalink
Weird, it works for me - please try
Write-Host "User: $($userlist_names_raw.Groups[$i].Value)"
instead and let me know what it yields :)
Dec, 2020 - Permalink
I got the following after changing that line.
At C:\Users\XuserX\Desktop\lastlogin.ps1:44 char:60
+ Write-Host "User: $($userlist_names_raw.Groups[$i].Value)"
+ ~
Missing closing ')' in expression.
At C:\Users\XuserX\Desktop\lastlogin.ps1:49 char:1
+ )
+ ~
Unexpected token ')' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : MissingEndParenthesisInExpression
Dec, 2020 - Permalink
Hello team! I have an issue with script, could anybody helps me with it?
We use post facelift version. PS ISE runs script correct, we see users and their activity. But when i add EXE/XML sensor i have an error:
"XML: The returned XML does not match the expected schema. (code: PE233) -- JSON: The returned JSON does not match the expected structure (#O2). (code: PE231)"
I will be grateful for any advice.
May, 2022 - Permalink
Hi there,
Did you change write-host to write-output already? We did some security changes in one of the latest version and therefore write-host won't work anymore in default.
Kind regards
Felix Wiesneth - Team Tech Support
May, 2022 - Permalink
This article applies to PRTG Network Monitor 16 or later
How to Show Last Logins of all PRTG Users
PRTG can show the time when a user logged in the last time, but if you want to cleanup the user database, then this is the fast way to display inactive users.
Please copy and save the script that we provide below as <name>.ps1 and alter the parameters displayed in the head of the script:
-server "<address of PRTG server>"
-username "<username of a PRTG Administrator user>"
-passhash "<passhash of the PRTG Administrator user>"
Note: You can find the required passhash under Setup | Account Settings | My Account. Click Show Passhash to display it (see PRTG Manual: Account Settings—My Account).
After the execution of the script, you will receive a result like this:
The list will allow you to add filter criteria for each column and show all configured users.
Script for post-facelift (version 17.x.35 or later)
Script for pre-facelift (versions prior 17.x.35)
Changelog:
13.02.2017 - Added "count=" parameter to the request of the user list, now the script will display more than 50 Users.
15.03.2017 - Added Login-Name Column 08.01.2019 - Changed script to work with facelift
Feb, 2017 - Permalink