Monday, June 5, 2017

Everyday Powershell - Part 43 - Automatically Resume Failed HyperV Replication

Everyday Powershell, as useful as HyperV Replication.

So on our 2012R2 HyperV boxes we occasionally get problems with replication. Usually after a Windows Update related reboot.

So we could go through each of the VMs failed Replications, right click, resume replication but what are we? Barbarians?!?

We've scheduled the following script  to run on our hypervisors;

$hypervisor = "someserver"

$vms = Get-VMReplication -ComputerName $hypervisor | where health -eq "critical" | where state -ne replicating | where name -ne "someservertoexclude"

foreach($vm in $vms){
    while((Get-VM -ComputerName $hypervisor -VMName $ | where ReplicationState -ne "disabled" | get-vmReplication).state -ne "Replicating"){
        (get-VM -ComputerName $hypervisor -VMName $ | where ReplicationState -ne "disabled" | get-vmReplication).state
        if ((get-VM -ComputerName $hypervisor -VMName $ | where ReplicationState -ne "disabled" | get-vmReplication).state -ne "Resynchronizing"){
            get-vm $ -ComputerName $hypervisor | Resume-VMReplication -Resynchronize
            get-vm $ -ComputerName $hypervisor | Resume-VMReplication -Continue
            get-vm $ -ComputerName $hypervisor | Resume-VMReplication
            get-vm $ -ComputerName $hypervisor | get-VMReplication
        start-sleep -Seconds 10

get-vm -ComputerName $hypervisor | where health -eq "warning" | foreach-object {Reset-VMReplicationStatistics $}

So now when replication goes to hell because of a reboot, all the VMs just politley get back in line and do as they're told!

Friday, May 5, 2017

Everyday Powershell - Part 42 - Creating and populating Groups

Everyday Powershell, as useful as a loosely typed variable. In that sometime it's great others it can ruin your day!

So we're following on from last time where we learned the resolution of all the monitors we could talk to.

Now we're going to do something with that data.
import-csv C:\temp\monitoraudit.csv | where pcon -eq $true | where ScreenWidth -ne "" | ForEach-Object{
    $temp = "" | select pc, resolutionstring
    $temp.pc = $_.computername
    $temp.resolutionstring = ("PCs with screens at " + $_.ScreenWidth + "x" + $_.ScreenHeight)
    $test = $null
    $test = get-adgroup $temp.resolutionstring
    if($test -eq $null){
        New-ADGroup -GroupScope DomainLocal -Name $temp.resolutionstring
    Add-ADGroupMember $temp.resolutionstring -Members (get-adcomputer $temp.pc)
We use another foreach-object to jump over each row in our CSV
  • setup another temp object 
  • fill the temp object if useful information, PC name and a string with the resolution
  • we check if an AD group with the name of our string exists
  • if it doesn't we create the group
  • then we add the PC Name to the AD group
So what can we do with this? Well it's really useful to had AD groups with all your machines resolutions. You can;
  • See who management likes
  • Create interesting reports on which monitors should be replaced
  • Use the groups to apply policies to
The last one is what we're doing this for. We'll use these groups to target customised wallpapers, screen savers and login screens.

Friday, April 28, 2017

Everyday Powershell - Part 41 - Get Screen Resolution from remote PCs

Everyday powershell. It's not updated everyday, it's tools you could use daily.

You know sometimes you just need to know what resolution all your computers are running.
get-adcomputer -Filter {operatingsystem -like "Windows 7*"-Properties operatingsystem | ForEach-Object {
    $temp = "" | select computername, ScreenHeight, ScreenWidth, pcon
    $temp.pcon = Test-Connection $ -Count 1 -Quiet
    $temp.computername = $
        $resolution = Get-WmiObject -ComputerName $ -Class Win32_DesktopMonitor
        $temp.ScreenHeight = $resolution.ScreenHeight
        $temp.ScreenWidth  = $resolution.ScreenWidth
    $temp | export-csv C:\temp\monitoraudit.csv -Append

Check out the filter on the first line, that can be anything. We just needed Windows 7 machines.

It's a pretty easy foreach-object;

  • sets up a temp object in my favorite manner,
  • pings the machine to make sure it's up,
  • pulls the info we need from WMI
  • then bangs it out to the console and a CSV.
Hitting up each machine with a WMI query gets us fast results but it's not exactly complete. You could rejig this so that it ran as part of a login script or schedule it to run daily.

Why do we need this info? Well that's for next time when we'll do something useful with this data set we've created.