powershell

ActiveDirectory/LDAP result limits – MaxPageSize

ns a website from a systems administrator for systems administrators Home IT-Admins CMDB IT-Admins tool IT Search EOL Solutions Blog Contact Links ActiveDirectory/LDAP result limits – MaxPageSize

ActiveDirectory, respective LDAP, has a result limit setting, MaxPageSize. Those are set by default to 1000 rows per query.

This is primarily important if you use some kind of programming language to get results from LDAP, this code must compensate those limits and engage paging.

Your LDAP query does not need to provide the limit, only the code needs to do the paging as you always just get the max. amount of results set in the current settings.

In order to check your settings do the following commands in a command prompt / cmd window:

In theory you could set different values now as well, assuming you have the permission level to do so. But this is not recommended and you should engage paging instead, as you otherwise risk to overload your DCs – even if your commands won’t cause it, a possibly DoS attack could happen – malicious or not, so leave the limits, but be aware of them.

 

Monitoring relative printer page counts with PRTG

Monitoring relative printer page counts with PRTG

PRTG has many standard sensors, but one I was always missing is a daily page count compare. The standard printer sensor gives you a total page count – but this to some extend will always be a graph that only will go up. You can only estimate the total page counts in those graphs.

If you ever looked in to the IT Assets database project, you will see that in the Printers area there is a possibility to enable detailed graphs for relative page counts.

Why is this important you might wonder. The answer is simple, as an IT Manager you need to know if a certain kind of a printer makes sense at a certain location. If you have a low end printer for only casual print-outs but you have a total over e.g. 10,000 pages printed every month, you might need to reconsider the printer model. The reasons would likely be:

  • higher cost per page
    • constant toner exchange of a compared more expensive toner cartridge
  • maintenance cost
    • you might need to constantly maintenance the printer
    • the cost for the maintenance kit are relatively high
  • downtime issues
    • due to toner empty
    • printer needs maintenance again
    • less pages in paper tray

On the other hand, a printer might also be overkill for a certain area and not be cost efficient. Those conditions also might change over time of course. Further is there often the question – is a single area printer (copier) better or multiple smaller printers. This of course can go pretty far and you want to consider Lean processes, Six Sigma guidelines and others along with this data.

How ever, I started a first draft of a script that provides me at least the total page count relative to each day in PRTG. This sure is not as efficient yet as I do this in the IT Assets database printer module, where I collect data e.g. every 30 minutes in a huge table and then later calculate all the data in a daily range respective monthly range while collecting total page counts and possibly counts per copy vs. print outs and additionally color vs. black and white print. But at least it is a start.

Below you find the first draft of this script.

One thing to know – you will need to run the following command in order to install the PowerShell SNMP module on your PRTG probing server:

The current version of the PRTG script:

Office 365 licenses and activated features per user

Office 365 licenses and activated features per user

Ever wondered which user has what license activated and e.g. which specific feature is activated? Recently I was challenged to see who has the Exchange mailbox feature enabled and who not out of the active user base. Due to the huge user-base this would have taken hours to review manually. Using PowerShell for this, connecting to Office 365, exporting the data eventually to a CSV file and filtering it in Microsoft Excel made this way easier.

The challenge here is that Microsoft uses SKU’s – or licenses – that again can have various features enabled or disabled. Let’s say you have a E5 Plan (license) assigned to your user, you still can disabled various features within this plan, e.g. Microsoft Exchange.

If you take a look at the following website, you find a whole list of GUIDs / IDs of all those various features.

https://docs.microsoft.com/en-us/azure/active-directory/users-groups-roles/licensing-service-plan-reference

In case of the Microsoft Exchange Mailbox feature – we are talking about this GUID: efb87545-963c-4e0d-99df-69c6916d9eb0

Once I had identified the GUID the next step was to grab users from a specific on premise Active Directory OU and query them against Microsoft Azure on the Office 365 environment as for their assigned licenses/features. The results then are collected in a PowerShell object and eventually saved in a defined file name in a CSV format that you easily can filter in Excel afterwards.

Please keep in mind that you will need RSAT tools (PowerShell) and Azure/Office 365 connectivity, rights etc. in order for this to work.

 

PRTG and VMware 6.7 vCenter host hardware status

PRTG and VMware 6.7 vCenter host hardware status

The following script was created to bypass an issue in the SOAP API in relation with VMware, hardware vendor drivers and PRTG. In any case, you could use the same script for other monitoring systems or any other purpose – of course while adjusting it to your needs.

You can find more information about the issue here: https://kb.paessler.com/en/topic/82458-vmware-host-hardware-status-soap-sensor-returns-warnings-after-update-to-vmware-6-7

In order to make this work you need to install the VMware PowerCLI PowerShell extension on the PRTG probe server. Further will you need to inject username and password as well as the vCenter name and internal hostname in vCenter.

LDAP authentication activated targets:

  • $host %host “%windowsdomain\%windowsuser” “%windowspassword”
  • $host %host.domain.local “%windowsdomain\%windowsuser” “%windowspassword”

Otherwise – you might need to use this format:

  • $host %host root MyRootPW

Test it in PowerShell as the Probe-User first – you should see the results. Eventually the script create a sensor with multiple channels – sensors in GREEN status will be counted only – sensors in UNKNOWN status will be counted and returned as text, while as long as no YELLOW or RED status (warning or error) occurs, the sensor still stays green/okay. Warning or Error levels will automatically apply and have the problematic hardware systems in the sensor message text.

My first attempt was to show all channels on top of the summary – due to getting over 100 separate hardware statuses back and the limitation in PRTG of 50 channels per sensor, I dropped the idea – while the script still has all the code to handle it.

 

Search the Windows Security Eventlog for a string / text

Search the Windows Security Eventlog for a string / text

Lately I had to search a lot through logs – as you can tell by all my postings… I just had to create yet another script that allows you to search through the Windows Security Eventlog – while the script is easily adjustable to other log types like application log or system log.

It’s not the most pretty script – but it certainly works. Don’t be surprised if the script takes it sweet time – it might be it needs to read through a lot of eventlog entries.

 

Active Directory password reset events and group change events

Active Directory password reset events and group change events

The script below uses the security event log on defined DCs within your Active Directory to export events related to certain activities. Eventually the script will export this even to an email and send it to you as a report – if needed.

As is – the script will specifically look for those events

  • 4724 – a user password was reset by an administrator respective via Active Directory Users and Groups MMC (or similar)
  • 4728 – a user was added to a security group
  • 4729 – a user was removed from a security group

There are more events – specifically events related to adding/removing users from distribution groups etc. – for the purpose of for what I wrote the script, I did not need this. Still, I thought it is worth publishing this, as others might find it helpful.

To add more events – just adjust line 19 – eventually just add more “or EventID=1234” statements – should be rather easy… in theory you could build that out as a parameter as well and inject it via the script.

 

APC InRow A/C error monitoring with PRTG

APC InRow A/C error monitoring with PRTG

It is rather hard to get valuable alarm monitoring from an APC InRow air conditioning unit. The APC A/C’s are a real pain when it comes to this, it might even be that this same principle applies to APC UPS units, but I did not have yet time to test this out.

What I really wanted is a way to monitor alerts that the unit reports. Doing so seemed to be fine with a simple SNMP sensor in PRTG but the real challenge was getting the alert text. Now, there are SNMP channels but they are only available when an alert is ongoing, meaning when there is no alert status the whole OID fails.

To compensate this, I ended up writing a simple PowerShell script that interprets the SNMP OID results, even ignores a certain failure cause I didn’t care about it, and reports back the results as a total error count (set the channel to ErrorLimit = 0 in PRTG) and if there are Errors it will write them to the text.

This is an Advanced EXE script that needs to reside in the following path:

It expects the parameters for community and IP-Address

The results of the script will always hold the top 4 error messages, but it will exclude the phrase “No Backup Units Available Alarm” from the error count – cause in certain setups like hours there are multiple units but they are not necessarily clustered – this is not a full alarm rather then a warning in my case. Feel free to adjust this in the script if you want to raise the error. You could simply remove / remark the following line:

Here a picture of a real world alarm respective issue with the APC InRow A/C in PRTG generated by the script

Move user Documents and Desktop to OneDrive

Move user Documents and Desktop to OneDrive

The PowerShell script below was design to move Documents, Music, Videos, Pictures, Favorites and Desktop to a sub-folder in a connected OneDrive. In theory the script does not depend on OneDrive and could be adjusted to any other destination.

While it normally is wise to engage GPOs to adjust those paths to internal server resources, this is not possible easily while using OneDrive. The script therefor works better here.

What it does

  1. is the current path per folder accessible
  2. does the target path exist
    1. YES: adjust the registry respective folder targets to the target path – FINISHED
    2. NO: create the target folders – see 3.
  3. is the source path on the same volume / partition – like C:
    1. YES: see below – 4.
    2. NO: check if there is enough free space for the amount of data needed to be moved
      1. YES: see below – 4.
      2. ALMOST: YELLOW warning – see below 4.
      3. NO: RED error – you could still proceed or simply close the script
  4. move the data to the new target folder
  5. remove the old folder – if not possible rename it

The script retains the special icons for the folders and engages the Windows API to adjust the folder paths.

What you need to do

  • Adjust the target-path in the top of the script
  • If desired, adjust the minimum free space value (2 GB by default) for the warning in regards to the free space – this only matters if the source and target volume / partition aren’t the same

To start the script, either right click and say run with PowerShell or run it directly in a PowerShell. This script will need to execute in the user-context and does NOT need administrative rights.

Please be advised – the script will by default not try to move e.g. DOWNLOADS.

You can adjust this, while adding the folder to the two parameter, see sample below.

If you want more folder, the script would need some special adjustments. It can be used as a base script, if you want.

 

Compare a TRACEROUTE against an expected route

Compare a TRACEROUTE against an expected route

Some times it is important to know if a route to a specific target changed. The best way to check this is for sure to engage a monitoring software. But there might not be a real standard solution in the monitoring software. Now you end up wondering how should you approach this and find a solution to monitor a traceroute result and the hops between you and the target and find out if something changed.

For this exact case I wrote a PowerShell script that expects the following two parameter:

  1. a target IP address or DNS name
  2. a list of IP addresses in order as they should come up in the traceroute (comma separated)
    1. include the target IP address as a final HOP

The script then will execute a tracert or traceroute to the target and compare the results step by step against the IP address list you injected. If a HOP is different at a certain position from what was expected an error will be reported back which IP was found and which was expected.

If there are no differences as for the injected IP list, it still could be the case that the traceroute to the target was e.g. longer or shorter – if there then is a difference in the HOP count between the actual traceroute results and the injected IP address list you still will get an error raised and a report back on the amount of found hops and expected hops.

Since the whole output is optimized to be processed by Paessler’s PRTG you also get an error from the sensor / script when the target was not reachable.

Additionally some information on the round-trip-time (RTT) and total HOPs is reported back to the sensor, ending up in a total of four channels:

  1. Target reached
  2. Round Trip Time
  3. Total HOPs
  4. Route matches expected route

As of September 2020 there are two versions of this script. First see the original script, after this I detail out the second version, see further below please.

As mentioned further above, after a request in September 2020 in the Paessler KB a version 2 of the script was created. This version includes a third needed parameter – Expected IP address. This also introduces a new channel, that will indicate if the expected IP was found or not (error status).

This can possibly help, as the requestor stated, to determine if route still goes over a primary gateway or a backup gateway. Sometimes you a route might change further below, but a certain router needs to be active. You could also easily change the expected IP behavior to not expected IP behavior, by changing the $ExpectedIPFound value in line 33 to 1 and in line 36 to 0. This will invert the script behavior for this function and therefor only alert (indicate) IF this IP suddenly appears on the route, besides the fact that the route will have changed anyways.

Request a DNS based web site directly from an IP address

Request a DNS based web site directly from an IP address

If you are using multiple web servers and some more advanced DNS configuration like e.g. Round-Robin (and other) to load balance and possibly even GEO divide traffic to those web servers while those are all hosting the same web site you might as well want to monitor if this is all working as expected.

The challenge in this case is – your monitoring system might get just a single IP that might even change every now and then back from DNS when it requests it from DNS. So you would end up needing to use the target IP addresses of the individual web servers instead. But those expect you that your request for the web site goes through the domain name, since the servers aren’t supposed to answer on direct host-name / IP address requests or another web-site might be hosted there.

In order to accomplish this – I wrote the script below. It allows you to request a website directly from an IP address while injecting the DNS host in the header section of the Invoke-WebRequest (IWR) in PowerShell.

If you need to target a specific target site you can inject of just the IP address additional information, for example:

  • Standard parameters
    • -DomainName “google.com” -IP “8.8.8.8”
      • this will request the web-root / default page
  • Sub-Page parameters
    • -DomainName “google.com” -IP “8.8.8.8/monitoring.html”
      • this will request the content of /monitoring.html on the IP 8.8.8.8 with the DNS name google.com

PS: Please be aware – the above will not work – 8.8.8.8 is a Google-DNS server and not one of their web-servers. The above is only an example to show what is possible.

The below script output was optimized to be used in PRTG.

 

Windows Search Index monitoring

Windows Search Index monitoring

While rolling out Windows Search Indexing I bumped in to quite a few issues and things I wanted to monitor. One of the main information I actually was after is the amount of files in the Windows Search Index. I could see this information in the Indexing Options of the system and it was constantly updating, but I was not able to find the same information per WMI, PowerShell cmdlets, Performance Counters etc.

This caused me headache cause it was clear that the index a) had to grow till it reached a fully indexed system and b) if the index-size dropped below a certain amount (once finished) I surely had an issue – I saw the database rebuilding out of no where – due to pagefile-issues or space on the partition where the index-database resided.

All of this made it clear that monitoring was inherent – but I did not want to play around with EventIDs – clearly the amount of files in the index was a way better indicator.

This caused me to write the following PowerShell script – it will invoke a command to a target system and count the files currently in the index. This has to be invoked, though the OLEDB provider of the Search Index allows remote-requests, it does not give you accurate numbers for the overall scope of the index on the system using remote requests. Getting to a point to even get this information was quite a challenge, I am certain who ever finds this here will know already, assuming you did some research. Hope it helps, though.

An update to this or what I learned

Of course you wouldn’t just monitor the amount of indexed files with the script above. You likely have a dedicated drive / partition where the index resides. You definitive want to monitor the used or free drive space there as well. What you will discover especially in the beginning but as well later if many files are moved or copied to the server, is that the Windows Search Index database will grow after the indexing of huge amounts of files is done and shrink again. As far as I understand this, there is some maintenance and deduplication going on.

On a server with about 14 million files that took about 1 week to index, I ended up with a 250 GB index database, the second it finished it took another 12 hours while the database grew another 100 GB and then shrunk back to actually 200 GB.

Don’t let those numbers scare you, we talk about 10 TB (terra byte) of data in those 14 million files. This is quite a bit. Most other file servers won’t have such huge databases and you won’t see such huge increases while the index database is doing some kind of clean up, nor will it take a week for the initial index to finish.

What I wanted to show with this is simply that you really want to monitor all those information and keep a close eye on it. I saw the database make huge jumps in size in very very short periods of time. If the drive then is full your index possibly would get corrupted and Windows will start from zero again. You want to avoid this. Once the index is finished and no huge incoming file operations take place you won’t see to many jumps anymore. It will calm down. But still, always make sure you have enough space on the partition where the index database resides and proper monitoring on it to be able to react quickly (going as far as automating a service stop for the Windows Search index while the space goes down to avoid database corruption).

Monitor the total amount of sessions on your RDS farm

ins a website from a systems administrator for systems administrators Home IT-Admins CMDB IT-Admins tool IT Search EOL Solutions Blog Contact Links Monitor the total amount of sessions on your RDS farm

This script is designed for PRTG and will allow you to go through all your RDS hosts and result back the total amount of sessions and active sessions.

You have various options as server name source, see the parameter section on top of the script.

This was also posted here: https://kb.paessler.com/en/topic/83151-total-user-count-rds-windows-2016

Please note that I grabbed the original script and re-wrote it completely, adjust some issues I encountered and tried to make it as variable as possible.

 

SNMP was deprecated

SNMP was deprecated

Microsoft deprecated the SNMP in Windows 2012 (R2). As of Windows 10 1809 respective Windows 2016 this feature is pretty much hidden. The decision likely was made due to security risks related to SNMP, in any case – as of right now it is still available if you really need it – but not via the good old Control Panel – Add Remove Features function. The following should even work on Windows 2019, since there is no indication that Microsoft finally removed the feature itself.

The following link is for Windows Server 2012 (R2) – it clearly states that SNMP is deprecated: https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-R2-and-2012/hh831568(v=ws.11)

Windows client and server operating systems share the same kernel in the background – for the most part.

Alternate ways to enable the feature:

  • using Apps & Features will help you getting SNMP via Optional Features
    • then use Add a feature
  • PowerShell commands:
    • Either those commands
    • or the following version of commands
  • or you use DISM on a command prompt

In all cases – you will run in to an possible issue if you use WSUS – you might need to temporarily bypass it in order to install this feature. It is possible that you need to restart the Windows Update service on the system for this setting to take effect.

  • Open Regedit and adjust the following key

It is pretty obvious that this feature will be removed at one point – but  as of now it is still available.

Let’s talk about a few things in regards to SNMP on Windows – or even in general when it comes to all your switches, firewalls, routers and other network components.

  • using SNMP on a Windows OS is a potential security risk – actually – SNMP itself is in general, cause it is standardized in often not locked down while having as well just limited security features
  • I personally don’t see a reason to use SNMP to monitor a Windows Server – the system itself can easily be monitored by WMI and other methods – that might have pro’s and con’s – but it generally works
  • There are circumstances then you need SNMP enabled – I had this while coming across mostly UPS software that only allowed to interact with it via SNMP – the UPS itself was connected per USB and the software on a Windows server/client allowed no API calls or similar – you had to enable SNMP on Windows and then use SNMP through Windows to grab data for e.g. UPS monitoring
    • having said this – this is actually a flaw by the vendor in such a case and should by addressed with the vendor
    • there is possibly more then just an UPS software that does behave like this

Read the UEFI stored Windows key and activate Windows

Read the UEFI stored Windows key and activate Windows

Ever wanted to read out the UEFI stored Windows key and probably automatically try to activate Windows with a single script?

The UEFI stored Windows license key is essential due to the fact that you don’t have a physical license anymore and you should keep it just in case for situations like your motherboard was exchanged and the key not transferred properly. I came across similar situations and was glad that I had the key.

But the script below does more then just reading and displaying the key – it will try to activate Windows as well.

Please note – it is wise to combine the read out of the key with an export and save method – like writing it to a database – this script will only show the basic functionality – but this is the most important part already.

The next two lines help additionally – if you create this batch file as well and store both files in the same directory, you simply can right click the .CMD file and execute it with elevated rights (run as administrator) and it will make your live even easier. This is just a simple trick to bypass some restrictions that you might encounter while trying to execute a PowerShell script with elevated rights and bypassing the execution policy for scripts at the same time.

VMware alert monitoring with PRTG and PowerShell

VMware alert monitoring with PRTG and PowerShell

There is a way to read out and process ALL alerts of your VMware environment using PowerShell and reporting the results back to PRTG. The script further down in this article does this. What you get is similar to the graphic here.

This show you the following channels:

  • Overall status
    • this will be green as long there aren’t any not acknowledged warnings or alerts in VMware
    • if the warning or alert is acknowledged, the sensor / script will return to green cause it is nothing that is new
  • Total Alerts – amount of alerts acknowledged and not ackowledged
  • Total Alerts – Acknowledged
  • Total Alerts – NOT Acknowledged
  • Total Warnings
  • Total Warnings – Acknowledged
  • Total Warnings – NOT Acknowledged
  • Total Warnings and Alerts
  • Total Warnings and Alerts – Acknowledged
  • Total Warnings and Alerts – NOT Acknowledged

As you can see – you can get more granular on your PRTG statuses if you use the channels for Warnings/Alerts that are acknowledged. You could set upper warning or error limits of 0 to keep a warning / error level in PRTG if you want to see them still.

While I was writing the script, I decided to create a new lookup value in PRTG to make it more clear. If you adjust the script in regards to add additional statuses for the channel overall status – you will need to adjust this file as well.

Let’s start with the value lookup file, you need to copy the text from the first script block in to a file you store here: C:\Program Files (x86)\PRTG Network Monitor\lookups\custom

Name the file: vmware.alerts.search.ovl

Now we need to create a custom EXE/XML sensor in this directory: C:\Program Files (x86)\PRTG Network Monitor\Custom Sensors\EXEXML

Name the file: VMwareAlerts.ps1

Once you have both files created, go to PRTG and add a new sensor called EXE/Script Advanced and select the new created script file. As Parameter you either type the host-name of your vSphere server or if you created it underneath the device in PRTG just use %host.

UPDATE: I changed the script cause I found it to be better to go with the following expected parameters and always making sure you have control over username and password used to connect to VMware. Please use the follow parameter moving forward:

There are still a few challenges you might need to overcome on top of this:

  • install the VMware PowerShell extensions on your PRTG probe server
  • credentials to connect to VMware can be a challenge as I tested this
    • you might need to have the service account of the PRTG probe have sufficient access rights – needs working SSO
    • alternative use a stored credentials file in PowerShell – somewhat secure
    • or provide the credentials clear text in PowerShell – least secure
    • please see line 20 respective the command “connect-viserver” for more details
  • updated the script – it now expects username and password as parameter

You might wanna test the script before you add a sensor to PRTG – the best way to do this is directly on the PRTG server with the service account of the PRTG probe to make sure it will work as a sensor later on.

Keep in mind that the script expects a parameter – the VMware vSphere server name / web-address.

This was also posted on the PRTG KB here.

 

Monitor multiple website certificates with a single PRTG sensor

Monitor multiple website certificates with a single PRTG sensor

Due to a request on the PRTG KB of someone needing a single sensor that monitors multiple URLs for their certificate expiration I came up with the following script that is posted on this PRTG KB as well. The modified PowerShell script was provided there – it is mentioned it sourced from Stack Overflow – I found it on this link: https://stackoverflow.com/questions/28386579/modifying-ssl-cert-check-powershell-script-to-loop-through-multiple-sites

The result would look like this:

To make it more usable – you can input parameters from PRTG like this:

or this for limits – warning 60 and error 10 – you could name them but this should work as well…

And here is the modified script:

 

Secured WinRM SSL session and PowerShell WinRM queries – example with a PRTG sensor for CPU, HDD and RAM

Secured WinRM SSL session and PowerShell WinRM queries – example with a PRTG sensor for CPU, HDD and RAM

Windows Mangement Remote Mangement / WinRM can be configured as HTTPS / encrypted connection instead of using clear text transfer of the provided information. In order to do this you need to configure it accordingly and have a valid machine certificate installed on the system.

Now – the advantage here is clearly the added security layer while you request and receive those information. More information on how to do this can be found here: https://support.microsoft.com/en-us/help/2019527/how-to-configure-winrm-for-https

Only it becomes a challenge when you want to use PowerShell and e.g. PRTG to use this HTTPS encrypted system. I came across this request and had to create a script that actually works with such an HTTPS encrypted SSL session to WinRM. You can find it below.

What it does is rather simple:

  • set the CimSessionOptions to use SSL
    • additionally it bypasses the certification checks by default – you might want to adjust this depending on your network configuration
  • it creates a new CimSession to your target system using the UseSSL option
  • and finally it executes a few queries against this session
  • the data in this example is then translated in to a PRTG compatible XML structure so you could use it in a Advanced EXE/XML sensor within PRTG

The data in this example combines information about the CPU(s), HardDrives / HDD(s) (only installed drives, not USB) and Memory usage to PRTG in a single sensor while using channels.

Due to some dynamic of the script, you want to make sure you have fixed upper and lower error limits on especially the channel Total Disks – so if something changes you can re-create the sensor due to it’s fixed channels once it did run the first time.

In theory you could provide limits within the XML response to PRTG – this is up to you – I always liked it more to configure them solely in PRTG in the sensor channels so I could adjust them per device.

PS: This was originally posted in the private PRTG channel on SpiceWorks here.