Changing Registry entries on multiple systems with PowerShell and Remoting

 

A few weeks ago, a colleague asked if I knew of a way to script the change or modification of the Registered Owner / Organization information on a Windows Server system (2003 or 2008). I knew that this could be achieved with PowerShell and had some initial ideas, so I spent a few minutes whipping up the script below.

For this to work, you should ideally have all systems on the same Windows Domain and have enabled PowerShell remoting on each system that needs to be changed. Of course you could also just run the script on a single workstation/server on its own without the need for PSRemoting.

 

# On all remote machines that need their info changed
Set-ExecutionPolicy RemoteSigned
Enable-PSRemoting # Say yes to all prompts
#region This part only needed if machines do not belong to the same domain...
# Note: This can be a security risk, only use if you are sure you want to allow any host as a trusted host. (e.g. fine for lab environments)
cd wsman::localhost\client
Set-Item .\TrustedHosts * # Say yes to all prompts
#endregion
# Run on your management machine/machine you are using to update all others...
$computers = @("SERVER1","SERVER2","SERVER3")

foreach ($computer in $computers) {
    Enter-PSSession $computer
    cd 'HKLM:\Software\Microsoft\Windows NT\CurrentVersion'
    Set-ItemProperty -Path . -Name "RegisteredOwner" -Value "Auth User"
    Set-ItemProperty -Path . -Name "RegisteredOrganization" -Value "Lab"
    Exit-PSSession
}

 

So the above should update your registered owner and organization details for each server listed in the $computers array. (Specify your own host names here). The above script should be easy enough to modify if you are looking to change other registry entries. Finally, don’t forget that you should always be careful when updating registry, especially via script – make sure you have backups!

 

How to use PoSH or PowerCLI to SSH into network devices – wodSSH [Part 2]

 

In [part 1] of this series of posts, I explored SharpSSH, and how to use this to SSH into network devices via PowerShell or PowerCLI. I found this extremely useful, and managed to automate a process of retrieving some SHA1 SSL fingerprints from a few clusters of ESX hosts in the process. I did however find that loading the dll and functions necessary to get this bit of automation done was a little tedious. I had heard about wodSSH via the get-scripting podcast and decided I would need to take a look at this.

 

If you are planning on using wodSSH, you should start by downloading it here. Note that you should definitely buy a license if you are going to be using this for your job or day to day automation – the license is not to expensive if you consider the kinds of automation you could achieve with this! For this blog post I am just using the trial version in my lab environment at home to try out – the trial pops up a “nag screen” every now and then to indicate you are unlicensed. Once downloaded, install wodSSH and the libraries will now be available for use on your machine.

 

Download the script below, or take a look at it in the Syntax Highlighted area below – this is an example of how I was able to SSH into a cluster of ESXi hosts and run a remote command via SSH through PowerCLI. In this example, a table is returned with Host names, along with their SHA1 fingerprint information. It is possible to retrieve this info (as of ESXi 5 I believe) in PowerCLI, but for this example I just wanted to demonstrate the use of SSH and PowerShell / PowerCLI.

 

[download id=”14″]

 

$login = "root"
$password = "yourrootpassword" 

$Report = @()
$VMHosts = Get-VMHost | Where {$_.ConnectionState -eq "Connected"} | Sort Name

foreach ($vmhost in $VMHosts) {
	$hostname = $vmhost
	$ssh = New-Object -ComObject "weOnlyDo.wodSSHCom.1"
	$ssh.Hostname = $hostname
	$ssh.Login = $login
	$ssh.Password = $password
	$ssh.Blocking = 1
	$ssh.Protocol = 4
	$ssh.Timeout = 25
	$ssh.Connect($hostname)
	$ssh.WaitFor("regex:[$%#>] $")
	$cmdresult = $ssh.Execute("openssl x509 -sha1 -in /etc/vmware/ssl/rui.crt -noout -fingerprint`r`n","regex:[~#]")
	$ssh.Disconnect()
	$temp = $cmdresult | select-string -pattern "SHA1 Fingerprint="
	Write-Host $cmdresult -ForegroundColor Green
	$row = New-Object -TypeName PSObject -Property @{
		SHA1 = $cmdresult
		HostName = $vmhost
	}
	$Report += $row
}
$Report

 

You will notice that on line 09, we load the wodSSH library using the New-Object cmdlet. After this we continue to setup some properties for our $ssh connection object. A regex check is used to determine when are connected to a host and have an SSH shell prompt ($ssh.WaitFor(“regex:[$%>;] $”).  We then use $cmdresult to capture the result of running an SSH command via our connection to our current ESXi host. To finish capturing the output of the command on our remote host, we use a regex check again (“regex:[~#]”). You’ll notice that the actual command is also on this line, i.e. line 18 (openssl). After the result is captured, we disconnect our SSH session, then proceed to build our small report array. At the end of the script, we output the $Report array to the screen.

 

Results of the above script in PowerCLI

 

As far as I can see, the wodSSH library can open up a whole new world of automation for you in the data centre. Think of the possibilities – you could automate just about everything, from switches, routers, Linux/Unix hosts / ESXi Hosts to iLO / DRAC and other management cards. Essentially, anything that accepts commands via SSH! If you have any automation stories using wodSSH, or just PowerShell or PowerCLI in general, I would love to hear about them – so feel free to drop a comment or two on this post.

 

 

How to use PoSH or PowerCLI to SSH into Devices & retrieve information (Gathering SHA1 Fingerprints)

 

I was listening to GetScripting podcast #29 the other day. The guest was Pete Rossi (PoSH Pete), and in the discussion he discussed data centre automation. Part of the automation he has set up involves wrapping SSH with PowerShell, and by doing so he is able to automate various functions on devices that can be SSH’d onto. This got me thinking of potential use cases. Soon enough I already had a couple of use case scenarios that could do with automating using SSH and PowerCLI. Pete mentioned he mainly uses an SSH component by a company called “WeOnlyDo Software”, however Alan Renouf also mentioned having heard of “SharpSSH”. I decided I wanted to try both out and figure out how to use both, so with that I set out figuring out how to get them working with PowerShell and PowerCLI. In this post (Part 1) I will cover using the SharpSSH DLL. In Part 2 I will go into the (easier in my opinion) wodSSH component (also paid for) method.

 

SharpSSH (based on Tamir Gal’s .NET library)

 

I believe Tamir Gal originally created this library, however it seems to now be maintained by others.

 

First of all, for SharpSSH to work with PowerShell or PowerCLI, you’ll need to get the relevant DLL that will be loaded by your script. I found a version of SharpSSH being actively worked on and improved by Matt Wagner on Bitbucket. I downloaded this version (called SharpSSH.a7de40d119c7.dll) to get started. To load the functions that we’ll be using to SSH in to devices, I used the following PowerShell function. Just be sure to reference in the correct path of the SharpSSH DLL that you downloaded above in this function. Download the function below:

 

[download id=”13″]

 

Then as long as the functions are loaded in your PoSH session, you should be able to run the example below.

 

How to SSH into ESXi hosts and retrieve SHA1 Fingerprints using PowerCLI and SharpSSH

 

Example output after running the script detailed below against multiple ESX hosts

 

 

Now, first off I’ll say that this isn’t necessarily the best way of retrieving SSL Fingerprints from your ESXi hosts in terms of security – you’d want to do this from the DCUI of the ESXi hosts to confirm the identity of each host is as you expect. (See this blog post and comments over at Scott Lowe’s blog for more detail on the security considerations). With that being said, here is my implementation of SharpSSH, used to SSH into each ESXi host (from a Get-VMHost call) and retrieve the SHA1 Fingerprints. The script will create and output a table report, listing each ESX/ESXi host as well as their SHA1 Fingerprint signatures.

 

Background for the Script

 

I believe this is actually quite an easy bit of info to collect using PowerCLI and the ExtensionData.Config properties on newer hosts / vSphere 5, but in my environment I was working with, all my ESX 4.0 update 4 hosts did not contain this Fingerprint info in their ExtensionData sections when queried with PowerCLI. Therefore I automated the process using SSH as I could use the command “openssl x509 -sha1 -in /etc/vmware/ssl/rui.crt -noout -fingerprint” to generate the Fingerprint remotely on each host via SSH. So with that in mind, here is the script that fetches this info. Note it will prompt for root credentials on each host that is connected to – this could probably be easily changed in the Function (downloaded from above). So here is the final script which will list all ESXi hosts and their SHA1 Fingerprints:

 

$Report = @()
$VMHosts = Get-VMHost | Sort Name

foreach ($vmhost in $VMHosts) {
	New-SshSession root $vmhost
	if (Receive-SSH '#')
	{
		Write-Host "Logged in as root." -ForegroundColor Green
		$a = Invoke-SSH "openssl x509 -sha1 -in /etc/vmware/ssl/rui.crt -noout -fingerprint" 'SHA1'
		$temp = $a | select-string -pattern "SHA1 Fingerprint="
		$row = New-Object -TypeName PSObject -Property @{
			SHA1 = $temp
			HostName = $vmhost
		}
		$Report += $row
		$rootlogin = $true
		Write-Host "Output complete." -ForegroundColor Green
	}
	if ($rootlogin -eq $true)
	{
		Write-Host "Exiting SSH session."
		Send-SSH exit
	}
	Write-Host "Terminating Session."
	Remove-SshSession
}

$Report

 

Well, I hope this helps you out with a way to automate SSH access to devices to retrieve information or change settings. This could easily be adapted to send SSH commands to any other kind of device that accepts SSH as a method of login. Switches, Routers, linux servers, you name it! In my next blog post I will be showing you how to use the wodSSH library (We Only Do Software) to do SSH in PowerShell or PowerCLI – I have found this method to be a bit easier to use when compared with SharpSSH! So look out for my next post coming soon!

Get vCenter User Sessions and Idle times with PowerCLI

Today I was looking into a small “nice to have” notification system for users that had left their vSphere clients open and logged into vCenter. I found this great bit of script to list currently logged in users over at blog.vmpros.nl and thought I would expand on this in my own way to generate a handy list of logged in users and their current idle time – similar to the way the “Sessions” tab in the vSphere client displays user session information. When I got home this evening I expanded on the original script from vmpros.nl to create the following:

 

$Now = Get-Date
$Report = @()
$svcRef = new-object VMware.Vim.ManagedObjectReference
$svcRef.Type = "ServiceInstance"
$svcRef.Value = "ServiceInstance"
$serviceInstance = get-view $svcRef
$sessMgr = get-view $serviceInstance.Content.sessionManager
foreach ($sess in $sessMgr.SessionList){
   $time = $Now - $sess.LastActiveTime
   # Our time calculation returns a TimeSpan object instead of DateTime, therefore formatting needs to be done as follows:
   $SessionIdleTime = '{0:00}:{1:00}:{2:00}' -f $time.Hours, $time.Minutes, $time.Seconds
   $row = New-Object -Type PSObject -Property @{
   		Name = $sess.UserName
		LoginTime = $sess.LoginTime
		IdleTime = $SessionIdleTime
	} ## end New-Object
	$Report += $row
}
$Report

 

[download id=”6″]

 

Here is an example of the output of the script:

 

Using this bit of PowerCLI script, it should be easy for you to create your own notification system based on user session idle time, or some functionality that would disconnect idle users. Let me know if you do improve on the above, or if you have any other suggestions.

 

Veeam Backup stats report for all your VM Backup jobs in PowerShell

 

The other day I was asked to collect some statistics on our Veeam Backup & Recovery server from as many VM Backup jobs as possible. The environment has roughly 70 scheduled jobs thats run either daily or weekly. After searching around a bit first I could not find any current solution or built in method to retrieve the info I needed to collect in a quick or automated way. First ideas were to either somehow grab the info via SQL queries from the Veeam database, or to rather take a sampling of 10-20 different types of jobs and their backup sessions over one normal incremental run day, and one normal full backup day (Manually collecting this data from email reports would be quite a slow process).

 

After browsing around the Veeam Community Forums I suddenly remembered that there was a PowerShell module that Veeam Include with B&R. I read the basic documentation and got acquainted with a few simple cmdlets.  I wanted to build a report, that would loop through every single Veeam B&R Job we have, and grab data from the last 7 backup sessions of each (daily backups), therefore giving me a good idea of both full backup and incremental backup runs performance, times taken etc… My first attempt at a script got me almost all the way there (tried during spare time in my evenings!) – I was however having trouble matching backup session data with the right day’s backup file stats – sometimes the ordering was out, and I would get metrics back for a backup file that was not from the correct day. Before I was able to resolve this myself, help arrived from “ThomasMc” over at the Veeam Community Forums. (Thanks Thomas!) We got a script together that was able to match up sessions correctly. I then added a few more features, as well as some nice HTML formatting and the ability to grab statistics for all jobs instead of just one sample job. The resulting script gets the following info for you:

 

  • Index (1 = the last backup sesion, 2 = the day before that, etc)
  • Job Name
  • Start time of job
  • Stop time of job
  • File Name (Allows you to determine if the job was a full or incremental run)
  • Creation Time
  • Average Speed MB – average processing speed of the job
  • Duration – time the job took to complete
  • Result – Success/Warning/Failed (Failed is highlighted in red)

 

Here is an example of the report run on my Veeam Backup & Recovery Lab environment at home (Thanks to Veeam for the NFR licenses they gave out to VCPs earlier this year!)

 
[download id=”1″]
[download id=”8″]

 

So, to run the above script, launch a PowerShell session from within Veeam B&R (Tools -> PowerShell). This will make sure your PowerShell session launches with the Veeam Automation/PowerShell snapin. Execute the script and you’ll get an HTML file output to the root of your C:\ drive. By default, all jobs you have in Veeam will be detailed. If you wish to sample a specific job, or a job with a certain word/phrase in it, adjust the -match parameter for the Get-VBRJob cmdlet line near the top of the script. The default setting is an empty string – i.e. “”. To change how many sessions the the script fetches for each backup job, just change the “$sessionstofetch” variable defined at the top of the script.
I have added comments throughout the script for those interested in how it works. Lastly, you could also quite easily modify this script to e-mail you the report, or even run it as a scheduled task. Let me know if you need help doing this and I’ll gladly modify it as required.

 

Adding a Percent Free Property to your Get-Datastore cmdlet results using Add-Member

 

Update:

 

Thanks to Alan Renouf  (@alanrenouf) for pointing out the New-VIProperty cmdlet to me, I was able to go back to the drawing board and really shorten up my original PowerCLI script by using the New-VIProperty cmdlet. @PowerCLI on twitter also pointed this out shortly afterwards. So after taking a quick look at the reference documentation for the cmdlet, here is my new VIProperty to get the “PercentFree” for each Datastore object returned from the Get-Datastore cmdlet!

 

New-VIProperty -Name PercentFree -ObjectType Datastore -Value {"{0:N2}" -f ($args[0].FreeSpaceMB/$args[0].CapacityMB*100)} -Force

 

To use it, simply run the above in your PowerCLI session, then use “Get-Datastore | Select Name,PercentFree”. A better option would be to load the above New-VIProperty script into your PowerCLI / PowerShell profile. Taking it one step further, @LucD has kindly offered to add this to his VIProperty Module, which means you could instead, just load this module in to your profile and benefit from all the other great VIProperty extensions! Example usage below:

 

New-VIProperty -Name PercentFree -ObjectType Datastore -Value {"{0:N2}" -f ($args[0].FreeSpaceMB/$args[0].CapacityMB*100)} -Force
Get-Datastore | Select Name,FreeSpaceMB,CapacityMB,PercentFree

 

You can find tons of other great VIProperties, or even download the entire module over at LucD’s blog.

 

Original Post:

 

I have been using the Get-Datastore cmdlet quite frequently at my workplace lately – mainly to gather information on various datastores which I export to CSV, then plug into Excel to perform further sorting and calculations on. To save myself a step in Excel each time (creating columns in spreadsheets to show and format the Percent Free figure of each Datastore), I decided to add this into my PowerCLI script.

 

Below, I’ll show you a fairly simple script that will add a member “NoteProperty” (A property with a static value) to your Datastore PS Objects. In the script, we’ll grab all the Datastores based on a search criteria (by default this will get all Datastores or Datastores with the word “Shared” in their name, but you can change it to match what you would like), then we’ll iterate through each, calculate the Percentage of free space from the two figures that we are given back already from Get-Datastore (CapacityMB and FreeSpaceMB), and finally add the member property to the current datastore object. Once this is done, we’ll output the results of  the $datastores object using “Select” to show the Name, Free Space in MB, Capacity in MB, and Percent Free of each object contained within to a CSV file (Remove the | Export-Csv part on the end if you just want the results output to console instead).

 

 

function CalcPercent {
	param(
	[parameter(Mandatory = $true)]
	[int]$InputNum1,
	[parameter(Mandatory = $true)]
	[int]$InputNum2)
	$InputNum1 / $InputNum2*100
}

$datastores = Get-Datastore | Sort Name
ForEach ($ds in $datastores)
{
	if (($ds.Name -match "Shared") -or ($ds.Name -match ""))
	{
		$PercentFree = CalcPercent $ds.FreeSpaceMB $ds.CapacityMB
		$PercentFree = "{0:N2}" -f $PercentFree
		$ds | Add-Member -type NoteProperty -name PercentFree -value $PercentFree
	}
}
$datastores | Select Name,FreeSpaceMB,CapacityMB,PercentFree | Export-Csv c:\testcsv.csv

 

Here’s an example of our output:

 

Note that you could simplify the script by removing the function called “CalcPercent” and adding it to your PowerShell or PowerCLI environment profile. Hope this helps!