Contact

Subscribe via Email

Subscribe via RSS

Categories

Creative Commons Attribution 4.0 International License
© Rakhesh Sasidharan

Go through a group of servers and find whether a particular patch is installed

Patch Tuesday is upon us. Our pilot group of server was patched via SCCM but there were reports that 2012R2 servers were not picking up one of the patches. I wanted to quickly identify the servers that were missing patches. 

Our pilot servers are in two groups. So I did the following:

The first two lines basically enumerate the two groups. If it was just one group I could have replaced it with Get-ADGroupMember "GroupName"

The remaining code checks whether the server is online, filters out 2012 R2 servers (version number 6.3.9600), and makes a list of the servers along with the installed date of the hotfix I am interested in. If the hotfix is not installed, the date will be blank. Simple. 

Oh, and I wanted to get the output as and when it comes so I went with a Width=20 in the name field. I could have avoided that and gone for an -AutoSize but that would mean I’ll have to patiently wait for PowerShell to generate the entire output and then Format-Table to do an autosize. 

Update: While on the Win32_QuickFixEngineering WMI class I wanted to point out to these posts: [1], [2]

Worth keeping in mind that Win32_QuickFixEngineering (or QFE for short) only returns patches installed via the CBS (Component Based Servicing) – which is what Windows Updates do anyway. What this means, however, is that it does not return patches installed via an MSI/ MSP/ MSU. 

Reboot a bunch of ESXi hosts one after the other

Not a big deal, I know, but I felt like posting this. :)

Our HP Gen8 ESXi hosts were randomly crashing ever since we applied the latest ESXi 5.5 updates to them in December. Logged a call with HP and turns out until a proper fix is issued by VMware/ HPE we need to change a setting on all our hosts and reboot them. I didn’t want to do it manually, so I used PowerCLI to do it en masse.

Here’s the script I wrote to target Gen8 hosts and make the change:

I could have done the reboot along with this, but I didn’t want to. Instead I copy pasted the list of affected hosts into a text file (called ESXReboot.txt in the script below) and wrote another script to put them into maintenance mode and reboot one by one.

The screenshot output is slightly different from what you would get from the script as I modified it a bit since taking the screenshot. Functionality-wise there’s no change.

Windows Services – Fix unquoted path vulnerabilities using PowerShell

At work as part of some security certification we are running Nessus scans on all our systems and it came up with the following vulnerability – link. Read that link, it’s good info.

Basically if one of your Windows Service entries point to (say) “C:\Windows\Microsoft.NET\Framework64\v3.0\Windows Communication Foundation\SMSvcHost.exe” without the double quotes then one could potentially create a malicious file called Windows.exe at “C:\Windows\Microsoft.NET\Framework64\v3.0\Windows” and Windows will execute that file instead of parsing the full path and treating it as part of a folder name. That’s because Windows uses space as a delimiter between a command and its switches & arguments and so it could treat the entry as “C:\Windows\Microsoft.NET\Framework64\v3.0\Windows.exe” with arguments “Communication Foundation\SMSvcHost.exe“.

The solution for this is to find all such entries that contain a space, and if the path is not in double quotes then make it so. You have to do this in the registry, so you could either do it manually or make a script and do it en masse. I went the latter route so here’s something I created.

I am being lazy and not really offering input etc as I just expect a list of servers to be scanned in a file called “ServerNames.txt”. I have the above saved to a .ps1 file and I simply run it as .\Registry.ps1. Feel free to adapt to your needs.

What it does is that it connects to the server specified (provided they are online), tries to open the “services” key under HKLM (assuming it has access), and then enumerates all the subkeys that contain the service names and checks if the path has a space. It only matches against paths containing a .exe so it could miss out some stuff. Once it finds a match it extracts the bit up to the .exe, splits it along any spaces, and if there are more than one results (which means the path did have spaces) it encloses it in double quotes and replaces the original entry.

The code is smart enough to know it must correctly double quote something like "D:\Program Files (x86)\BigHand\BigHand Workflow Server 4.6\BHServer.exe /V:4.6" as "D:\Program Files (x86)\BigHand\BigHand Workflow Server 4.6\BHServer.exe" /V:4.6 and not "D:\Program Files (x86)\BigHand\BigHand Workflow Server 4.6\BHServer.exe /V:4.6".

By default it only displays results. An optional parameter -FixIt will also make the changes.

Example output:

Hope it helps!

PowerShell – List of machines with CPU and disk info

Had to come up with a list of machines and their CPU, disk info etc. Thought it better to make a small script for it.

Hope it helps someone.

Use PowerShell to get a list of GPOs without Authenticated Users in the delegation

Must have seen this recent Windows update that broke GPOs which were missing the Read permission for the “Authenticated Users” group. Solution is to get a list of these GPOs and add the “Authenticated Users” group to them. Here’s a one liner that gets you such a list –

This puts it into a file called GPOs.txt in the current directory. Remove/ Modify that last re-direct as needed.

Get a list of services and “Log On As” accounts

Wanted to find what account our NetBackup service is running under on a bunch of servers –

You have to use WMI for this coz Get-Service doesn’t show the Log On As user.

Wheee!! Had a tweet from Jeffrey Snover for this post.

 

 

Following on that tweet I noticed something odd.

The following command works –

Or this –

In the second one I am explicitly casting the arguments as an array.

But this variant doesn’t work –

That generates the following error –

Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)
At line:1 char:1
+ Get-WmiObject Win32_Service -cn $Servers -Filter ‘Name= “NetBackup Client Service …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Get-WmiObject], COMException
    + FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)
At line:1 char:1
+ Get-WmiObject Win32_Service -cn $Servers  -Filter ‘Name= “NetBackup Client Service …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Get-WmiObject], COMException
    + FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

The error is generated for each entry in the array.

It looks like when I pass the list of servers as an array variable PowerShell uses a different way to connect to each server (PowerShell remoting/ WinRM) while if I specify the list in-line it behaves differently. I didn’t search much on this but found this Reddit thread with the same issue. Something to keep in mind …

 

Configure NTP for multiple ESXi hosts

Following on my previous post I wanted to set NTP servers for my ESX servers and also start the service & allow firewall exceptions. Here’s what I did –

 

PowerShell Remoting Security links

Just some links I found on PowerShell remoting security –

Create multiple DNS records using PowerShell

I had to create multiple A DNS records of the format below –

Just 9 records, I could create them manually, but I thought let’s try and create en-mass using PowerShell. If you are on Windows Server 2012 and above, you have PowerShell cmdlets for DNS.

So I did the following –

To confirm they are created, the following helps –

Nice!

Find out which DCs in your domain have the DHCP service enabled

Use PowerShell –

Result is a table of DC names and the status of the “DHCP Server” service. If the service isn’t installed (i.e. the feature isn’t enabled) you get a blank.

Quickly get the last boot up time of a remote Windows machine

PowerShell:

Command Prompt/ WMI:

Double quotes are important for the WMI method.

PowerShell regexp match with lines above and below

Wasn’t aware of this until today when I needed to do this. The Select-String cmdlet in PowerShell can select strings based on a regexp (similar to findstr in regular command prompt) with the added benefit that it can also return context. Which is to say you can return the line that matches your pattern and also lines above or below it. Pretty cool!

In my case I needed to scan the output of portqry.exe and also get the UUIDs of the lines that match. These UUIDs are shown on the line above so I did something like this:

The -Context 1,0 switch is the key here. The first number tells the cmdlet how many lines before to show, the second number how many lines after.

Get a list of OUs with inheritance blocked & GPOs not applied

To get a list of OUs and the status of GPO inheritance:

To get a list of OUs that have GPO inheritance blocked:

To get a list of OUs that have GPO inheritance blocked and a don’t have a particular GPO applied to them directly:

There’s probably a better way to do this, but this is the best I could come up with …

User PowerShell/ PowerCLI to get VM space usage

Wanted to get the space used by all VMs across a bunch of our newer hosts –

There’s probably a way to show the total too but I used a separate pipeline for that –

 

Get a list of users in an OU along with last logged on date

Trivial stuff. Wanted to note it down someplace for future reference –