List “Missing” guest in SCVMM

Problem

You want to create a list of all the guests listed as “Missing” in System Center Virtual Machine Manager 2012. Missing guest are usually references to guest that were deleted manually outside of VMM. To fix this, you have to delete the guests manually from VMM. But before you delete them, it is a good idea to get input on the list, just in case one of them shouldn’t be missing. You can of course use a filter in SCVMM to display them on-screen, but I was not able to find an easy way to grab the list as text from the GUI.

Solution

Use Powershell! Run the following command in your VMM Powershell console:

Get-VM| Where-Object {$_.Status -eq 'Missing'} | Sort-Object Hostname | Select-Object HostName, Name, ComputerName, Status | Export-Csv .\Missing-guest-list.csv -NoTypeInformation

This will give you an excel compatible csv file with a list of missing VMs/guests. If you want the list to include all of the guests, regardless of status, just remove the Where-object clause like this:

Get-VM| Sort-Object Hostname | Select-Object HostName, Name, ComputerName, Status | Export-Csv .\Missing-guest-list.csv -NoTypeInformation

Or you can change ‘Missing’ to another status like “Stopped”, “Saved State”, “Unsupported Cluster Configuration” and so on.

 

 

Does your cluster have the recommended hotfixes?

From time to time, the good people at Microsoft publish a list of problems with failover clustering that has been resolved. This list, as all such bad/good news comes in the form of a KB, namely KB2784261. I check this list from time to time. Some of them relate to a specific issue, while others are more of the go-install-them-at-once type. As a general rule, I recommend installing ALL hotfixes regardless of the attached warning telling you to only install them if you experience a particular problem. In my experience, hotfixes are at least as stable as regular patches, if not better. That being said, sooner or later you will run across patches or hotfixes that will make a mess and give you a bad or very bad day. But then again, that is why cluster admins always fight for funding of a proper QA/T environment. Preferably one that is equal to the production system in every way possible.

Anyways, this results in having to check all my servers to see if they have the hotfixes installed. Luckily some are included in Microsoft Update, but some you have to install manually. To simplify this process, I made the following powershell script. It takes a list of hotfixes, and returns a list of the ones who are missing from the system. This script could easily be adapted to run against several servers at once, but I have to battle way to many internal firewalls to attempt such dark magic. Be aware that some hotfixes have multiple KB numbers and may not show up even if they are installed. This usually happens when updates are bundled together as a cummulative package or superseded by a new version. The best way to test if patch/hotfix X needs to be installed is to try to install it. The installer will tell you whether or not the patch is applicable.

Edit: Since the original, I have added KB lists for 2008 R2 and 2012 R2 based clusters. All you have to do is replace the ” $recommendedPatches = ” list with the one you need. Links to the correct KB list is included for each OS. I have also discovered that some of the hotfixes are available through Microsoft Update-Catalog, thus bypassing the captcha email hurdle.

2012 version

$menucolor = [System.ConsoleColor]::gray
write-host "╔═══════════════════════════════════════════════════════════════════════════════════════════╗"-ForegroundColor $menucolor
write-host "║                              Identify missing patches                                     ║"-ForegroundColor $menucolor
write-host "║                              Jan Kåre Lokna - lokna.no                                    ║"-ForegroundColor $menucolor
write-host "║                                       v 1.2                                               ║"-ForegroundColor $menucolor
write-host "║                                  Requires elevation: No                                   ║"-ForegroundColor $menucolor
write-host "╚═══════════════════════════════════════════════════════════════════════════════════════════╝"-ForegroundColor $menucolor
#List your patches here. Updated list of patches at http://support.microsoft.com/kb/2784261
$recommendedPatches = "KB2916993", "KB2929869","KB2913695", "KB2878635", "KB2894464", "KB2838043", "KB2803748", "KB2770917"
 
$missingPatches = @()
foreach($_ in $recommendedPatches){
    if (!(get-hotfix -id $_ -ea:0)) { 
        $missingPatches += $_ 
    }    
}
$intMissing = $missingPatches.Count
$intRecommended = $recommendedpatches.count
Write-Host "$env:COMPUTERNAME is missing $intMissing of $intRecommended patches:" 
$missingPatches

2008R2 Version

A list of recommended patches for Win 2008 R2 can be found here:  KB2545685

$recommendedPatches = "KB2531907", "KB2550886","KB2552040", "KB2494162", "KB2524478", "KB2520235"

2012 R2 Version

A list of recommended patches for Win 2012 R2 can be found here:  KB2920151

#All clusters
$recommendedPatches = "KB3130944", "KB3137691", "KB3139896", "KB3130939", "KB3123538", "KB3091057", "KB3013769", "KB3000850", "KB2919355"
#Hyper-V Clusters
$recommendedPatches = "KB3130944", "KB3137691", "KB3139896", "KB3130939", "KB3123538", "KB3091057", "KB3013769", "KB3000850", "KB2919355", "KB3090343", "KB3060678", "KB3063283", "KB3072380"

Hyper-V

If you are using the Hyper-V role, you can find additional fixes for 2012 R2 in KB2920151 below the general cluster hotfixes. If you use NVGRE, look at this list as well: KB2974503

Sample output (computer name redacted)

SNAGHTML2af111ec

Edit:

I have finally updated my script to remove those pesky red error messages seen in the sample above.

Creating firewall rules for SQL server using Powershell

On Win2012/Powershell 3 there is a commandlet called “New-NetFirewallRule” that allows for scripted creation of firewall rules. This makes it a lot easier to get them rules right. I have previously used GPO to push this to my SQL servers, but sadly I have discovered that it does not always work. For some reason, servers don’t like to have their firewall rules pushed by GPO. This meant I had to check them every time anyway, so I just resorted to creating them manually. But now, thanks to the wonders of Powershell 3, maybe I won’t have to do that again Smilefjes

More information about the commandlet can be found here: http://technet.microsoft.com/en-us/library/jj554908.aspx

Sample code

This code creates rules to allow the SQL server browser (UDP 1434), the standard engine port for two instances (TCP 1433 and 1434) and the default port for AOAG endpoints (TCP 5022).

New-NetFirewallRule -DisplayName "MSSQL BROWSER UDP" -Direction Inbound -LocalPort 1434 -Protocol UDP -Action Allow
New-NetFirewallRule -DisplayName "MSSQL ENGINE TCP" -Direction Inbound -LocalPort 1433-1434 -Protocol TCP -Action Allow
New-NetFirewallRule -DisplayName "MSSQL AOAG EP TCP" -Direction Inbound -LocalPort 5022 -Protocol TCP -Action Allow

SQLIO results parser

Ever since I first learned about it I have been a happy user of a powershell script for parsing the results of a SQLIO test run into Excel made by Mr. Jonathan Kehayias (blog). It takes the otherwise difficult to read results file and reduces it to an excel file including a couple of “management-friendly” charts  Smilefjes.

The original script can be found here.

Continue reading “SQLIO results parser”

Folder copy with logging in Powershell, and a bit about scripts in general

Problem

I have been trying for some time to find an easy method for keeping my scripts up to date on my servers. I could of course use robocopy or something like that, but I wanted something written in PS. I figured I would learn something along the way, and I also had hopes that this would be fairly easy to accomplish. It would seem I was wrong on the being easy part, or perhaps I have over-engineered it slightly Smilefjes som blunker.

Not wanting to re-invent the wheel, I summoned the powers of the closest search engine to get up with some samples I could build on. I am a bit prejudiced towards scripts from the web in general, as I usually find most scripts longer than a few lines have some logical bugs in them. Scripts are, in general, easy to get started with, but it is very difficult to produce robust scripts. I have debugged countless VB and Powershell scripts (both my own and those of others) who were working fine in the lab, and perhaps also in production, but suddenly they cease to function as expected. Usually this is caused by some simple logical error appearing due to changes in the environment the script is running in, but from time to time you come across some obscure scripting engine bug you have to program around. And of course you have the pure idiotic fails, such as creating vb-scripts requiring “On error resume next” at the top of the script. Those are usually doomed by design and can take days to debug. Since I am fairly proficient in C# I usually just write a small utility .exe instead, thus circumventing many of the problems altogether. Once you have spent 4 hours debugging an error caused by a misspelled variable name in the middle of a 200 line script, you start dreaming about the wonders of explicit variable declaration and intellisense. Anyways, I think that is enough ranting for one post.Smilefjes

Continue reading “Folder copy with logging in Powershell, and a bit about scripts in general”

Check if processes are running

Intended for use as part of a bigger script where you need to check if a process or processes are running or closed. Checks if an array of processes are running on the system, and counts how many of them are running in an integer variable.

#Declare variables
[Int]$intRunning = 0
[bool]$Debug = $true
 
#Main logic
function Main
{
	$menucolor = [System.ConsoleColor]::white
	write-host '-------------------------------------------------------------------'-ForegroundColor $menucolor
	write-host '|                 Check if processes are running                  |'-ForegroundColor $menucolor
	write-host '|                     <c> Jan Kåre Lokna                          |'-ForegroundColor $menucolor
	write-host '|                     v 1.0                                       |'-ForegroundColor $menucolor
	write-host '-------------------------------------------------------------------'-ForegroundColor $menucolor
	write-host 
	checkProcesses
}
 
#Check processes
function checkProcesses
{
	$processes = "iexplore", "winamp", "Opera", "dfdsafs"
 
	foreach ($process in $processes)
	{
		try
		{
			$s= Get-Process $process -ErrorAction stop
			if($Debug -eq $true) {write-host $process 'is running'-ForegroundColor Green}
			$intRunning = $intRunning + 1
		}
		catch
		{
			if($Debug) {write-host $process 'is not running' -ForegroundColor Magenta}
		}
	}
	if($Debug) {Write-host "Running processes: " $intRunning "of" $processes.count}
}
. Main
</c>

Reparere søkeindeksen på en databasekopi

Problem

Forsøk på å gjøre passiv databasekopi aktiv feiler med følgende melding:

Database copy [navn] on server [server] has content index catalog files in the following state: ‘Failed’.

Løsning

Sjekk om det gjelder flere baser ved å kjøre følgende script:

###############################################################################
###			Find database copies with failed ContentIndex State       		###
###			<c> Jan Kåre Lokna												###
###			v 1																###	
###############################################################################
try
	{
	#Get mailbox servers
	$Servers = Get-ExchangeServer | Where-Object {($_.ServerRole -match "Mailbox") }
	foreach($Server in $Servers)
	{
		Get-MailboxDatabaseCopyStatus -Server $Server.Name | Where-Object{($_.ContentIndexState -ne "Healthy")}
	}
}
catch [Exception]
{
	Write-Host "Something went horribly wrong..."
	Write-Host $_.Exception.TosSTring()
}
</c>

Eksempel på output:

Name Status CopyQueue ReplayQueue LastInspectedLogTime ContentIndex 
Length Length State 
---- ------ --------- ----------- -------------------- ------------ 
DB2\EXCserver2 Healthy 0 0 27.05.2011 13:51:07 Failed

Kjør følgende kommando for å hente data fra aktiv kopi:

Update-MailboxDatabaseCopy [name] -CatalogOnly

Name hentes fra output av skriptet over. Vær obs på at kommandoen kasnkje må kjøres på den server som eier databasekopien (EXCServer2 i eksempelet over).