Archive for the ‘Powershell’ Category

Powershell-How to query memory state via Get-WMIObject

March 27, 2017

here is a simple example how WMI queries can be call’d from powershell. this one is just an example and you can extend this by any system property like processors, available memory or even include disk space informations. all is about your needs and of course your creativity

$x = read-host -prompt "Please enter the machine name " 
""
$colItems = get-wmiobject -class "Win32_ComputerSystem" -namespace "root\CIMV2" -computername $x

foreach ($objItem in $colItems){
$displayGB = [math]::round($objItem.TotalPhysicalMemory/1024/1024/1024, 0)
$totalsockets=$colItems.NumberOfProcessors
write-host "Total Physical Memory:" $displayGB "GB"
write-host "Total CPU (Sockets) found:" $totalsockets
write-host "Model: " $objItem.Model
}

$colItems2 = get-wmiobject -class "Win32_Processor" -namespace "root\CIMV2" -computername $x

foreach ($objItem2 in $colItems2){
write-host "System Name:" $objItem2.SystemName
}
""

image

an example from a previous post, here I do calculate the memory pressure on a cluster node to identify oversubscribed hosts which can lead perf issues

image

Get-WMIObject
https://technet.microsoft.com/en-us/library/ee176860.aspx

WMIBrowser
https://wmie.codeplex.com/

the WMIBrowser is really useful when you do not know exactly what properties are available and how to call them

image

WMI is really powerful and nearly every Windows property can be called from there – Ok I see how you are thinking about all the creative ways now…Happy scripting Winking smile

Azure Powershell Part 2-Create VM

June 7, 2016

in previous post “Azure Powershell Part 1” we setup and establish a connection to Azure through Powershell, now we try to create a new VM in Azure

after we established the connection and entered relevant subscription information my your session you will be able to run from here

Step 1: Determine the ImageFamily
First you need to determine the ImageFamily or Label value for the specific image corresponding to the Azure virtual machine you want to create. You can get the list of available ImageFamily values with this command.

there is a bunch of Images out there and total list of ImageFamily you can get with Get-AzureVMImage | select ImageFamily –Unique

image

Once you identified the image you want to deploy, copy the ImageFamily name for next step

$family="<ImageFamily value>"
$image=Get-AzureVMImage | where { $_.ImageFamily -eq $family } | sort PublishedDate -Descending | select -ExpandProperty ImageName -First 1

In my scenario I will use “Windows Server 2012 R2 Datacenter” please pay attention

image

Please note in some cases, the image name is in the Label property instead of the ImageFamily value. If you didn’t find the image that you are looking for using the ImageFamily property, list the images by their Label property with this command –> Get-AzureVMImage | select Label –Unique

Step 2: Build your command set for VMDeploy
Build the rest of your command set by copying the appropriate set of blocks below into your new text file or the ISE and then filling in the variable values and removing the < and > characters

$vmname="<machine name>"
$vmsize="<Specify one: Small, Medium, Large, ExtraLarge, A5, A6, A7, A8, A9>"
$vm1=New-AzureVMConfig -Name $vmname -InstanceSize $vmsize -ImageName $image

the value vmsize basically defines the instance class with which you classify the hardware properties of your VM. more details on “Sizes for Cloud services” 

now I want to connect this VM to a existing VMSubnet and assign also a static IP. Get-AzureVNetConfig returns back a XML structure, to get more data you can use fl to see what contains inside the XML

image

here I see I have a VMSubnet called “MyLabNetwork” and CIDR is 10.0.0.0/8 (Class A). checking which IPs are available you can use Test-AzureStaticVNetIP run following query

image

good state, so we now know VMSubnet name, subnet range and we confirmed the IP is available

so all together total script to deploy new VM would look like this

###Step1 Add your Account
$userName = "<your organizational account user name>"
$securePassword = ConvertTo-SecureString -String "<your organizational account password>" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential($userName, $securePassword)
Add-AzureAccount -Credential $cred
###Step1 END

###Step2 Set your subscription and storage account
$subscr="<subscription name>"
$staccount="<storage account name>"
Select-AzureSubscription -SubscriptionName $subscr –Current
Set-AzureSubscription -SubscriptionName $subscr -CurrentStorageAccountName $staccount

###Step2 END

###Step3 – Determine ImageFamily and Build VMDeploy CommandSet
$vmname="MyLAB2012R2"
$family="Windows Server 2012 R2 Datacenter"
$vmsize="Small"
$vm1=New-AzureVMConfig -Name $vmname -InstanceSize $vmsize -ImageName $image
$cred=Get-Credential -Message "Type the name and password of the local administrator account."

$vm1 | Add-AzureProvisioningConfig -Windows -AdminUsername $cred.Username -Password $cred.GetNetworkCredential().Password
Test-AzureStaticVNetIP –VNetName "MyLabNetwork" –IPAddress 10.0.0.50
$vm1 | Set-AzureStaticVNetIP -IPAddress 10.0.0.50
$vm1 | Set-AzureSubnet -SubnetNames "MyLabNetwork"

###Step3 END

image 
image

till here, we “only” passed the values but didn’t really create the VM, the final command New-AzureVM is required to kick on the real deployment in Azure

New-AzureVM –ServiceName "<short name of the cloud service>" -VMs $vm1

image

Once deployment started you will see it in your Azure dashboard

image

image

more parameters are available for New-AzureVM commandlet here

Parameter Set: ExistingService

New-AzureVM -ServiceName <String> -VMs <PersistentVM[]> [-DeploymentLabel <String> ] [-DeploymentName <String> ] [-DnsSettings <DnsServer[]> ] [-InternalLoadBalancerConfig <InternalLoadBalancerConfig> ] [-ReservedIPName <String> ] [-VNetName <String> ] [-WaitForBoot] [ <CommonParameters>]

Parameter Set: CreateService

New-AzureVM -ServiceName <String> -VMs <PersistentVM[]> [-AffinityGroup <String> ] [-DeploymentLabel <String> ] [-DeploymentName <String> ] [-DnsSettings <DnsServer[]> ] [-InternalLoadBalancerConfig <InternalLoadBalancerConfig> ] [-Location <String> ] [-ReservedIPName <String> ] [-ReverseDnsFqdn <String> ] [-ServiceDescription <String> ] [-ServiceLabel <String> ] [-VNetName <String> ] [-WaitForBoot] [ <CommonParameters>]

Password need to comply with following security standards else deployment will fail because of password policy, also only following usernames “Admin1, Administrator, Admin”"…” can be used. to use custom admin names you need to use Add-AzureProvisioningConfig -Windows -AdminUsername "<Custom Admin Username>" -Password <YOURPASSWORD>

if you modify $creds you have to pass that again to VMs config

$vm1 | Add-AzureProvisioningConfig -Windows -AdminUsername "<Custom Admin Username>" -Password <YOURPASSWORD>

image

Quick Tipp, in case you run into any issues during deployment of VM you can use –debug which helps to determine why deployment is failing to proceed

Windows Azure Management Cmdlets
http://msdn.microsoft.com/en-us/library/windowsazure/jj152841

Sizes for Cloud Services
https://azure.microsoft.com/en-us/documentation/articles/cloud-services-sizes-specs/

Azure Limits and Quotas
https://azure.microsoft.com/en-us/documentation/articles/azure-subscription-service-limits/

Should I choose cloud services or something else?
https://azure.microsoft.com/en-us/documentation/articles/cloud-services-choose-me/

there are tons of options available when you are creating Virtual Machine in Azure like a.e Domain Join, additional disk, StaticIP (DIP) for more details around configuration possibilities check out the commandlet “Add-AzureProvisioningConfig”

Azure Powershell Part 1-Setup and Start

June 7, 2016

Using Powershell in Azure is a powerful and quick way to script and automate frequent coming tasks. starting with Azure Powershell there some pre-requisites, I won’t go into much details here but basically how to load / install the Azure Powershell module can be found here

Once you successfully installed Azure Powershell on your machine you can do have a bunch of new commands available

image

To get a better overview of all commandlets related to a specific module you can use a.e. Get-Command -Module Azure

image

Now we have to connect to Azure and set up subscription data so we have a connection to Azure

Step 1: Add your account
1.At the PowerShell prompt, type Add-AzureAccount and click Enter.
2.Type in the email address associated with your Azure subscription and click Continue.
3.Type in the password for your account.
4.Click Sign in.

image

you can do this interactively or you can script that

$cred = Get-Credential 
Add-AzureAccount -Credential $cred

image

or to automate this in a script to avoid pop-up you can also use

$userName = "<your organizational account user name>" $securePassword = ConvertTo-SecureString -String "<your organizational account password>" -AsPlainText -Force $cred = New-Object System.Management.Automation.PSCredential($userName, $securePassword) Add-AzureAccount -Credential $cred

Note: take security considerations into account when hard coding service accounts / passwords. consider decrypt/encrypt password in your scrip runtime

Step 2: Set your subscription and storage account

Set your Azure subscription and storage account by running these commands at the Windows PowerShell command prompt. Replace everything within the quotes, including the < and > characters, with the correct names.

$subscr="<subscription name>" $staccount="<storage account name>" Select-AzureSubscription -SubscriptionName $subscr –Current Set-AzureSubscription -SubscriptionName $subscr -CurrentStorageAccountName $staccount

You can get the correct subscription name from the SubscriptionName property of the output of the Get-AzureSubscription command. You can get the correct storage account name from the Label property of the output of the Get-AzureStorageAccount command after you run the Select-AzureSubscription command

Powershell-3rd Party modules

April 27, 2016

there are several 3rd party Powershell modules available which enables you to manage your devices like F5 BIG or Cisco UCS with Powershell. just from my experience, the functions are limited but at least if offers you ability to automate basic reoccurring stuff like a.e. backup configuration and also a good starter to develop your own crazy stuff. here are 2 which I use currently and which I can recommend to take a look at

F5 – BIGIP

https://devcentral.f5.com/questions/big-ip-configuration-backup-restore
https://devcentral.f5.com/d/microsoft-powershell-with-icontrol
https://support.f5.com/kb/en-us/solutions/public/11000/300/sol11318.html

Cisco UCS Powertool

https://communities.cisco.com/docs/DOC-37154

Around Cisco UCS you can also check out this site from joemar which provides lots of examples for management UCS centers

https://communities.cisco.com/people/joemar/content

there are many more out there so please share any 3rd party modules you would recommended and I will add them to this list

Thanks and stay tuned Winking smile

Ramazan

Powershell-Generate Automated CSVFreespace and Memory Report

December 4, 2014

This script relies the Hyper-V clusters are been managed by VMM but if you do not use VMM you can also modify based on your environment. It should just give you an idea how to collect data and use sentmail function to get a daily report of your resource status.

Note: script version 1.3 is targeted to be run as a task so no console outputs are considered, just a logfile is written into same folder where is script is located

as no user interaction is possible because we want to use this as a task following variables has to be updated in the script

$VMMServer = "YOURVMMSERVER"
$smtpServer = "YOURSMTP"
$smtpFrom = "johndoe@mydomain.com"
$SMTPPort = "25"
$Username = "johndoe@mydomain.com"
$Password = ‘YOURPASSWORD’
$smtpTo = reports@mydomain.com

#
#Creator: Ramazan Can
#V1.2 	- dumping into log and generating mail with function "SentReportviaMail"
#		- mail sender, recipient, account for authentification can be modified in function "SentReportviaMail"
# 				$smtpFrom - $Username - $smtpTo 
#V1.3	- task scheduler version

#Write-Host " "
import-module virtualmachinemanager
import-module failoverclusters
$VMMServer = "YOURVMMSERVER"
$VMMClusters=(Get-SCVMHostCluster -vmmserver $VMMServer).Name
$timestamp=(get-date -Format d).Replace("/","_")
$date=Get-date
Get-item ".\CSVandMemory_Report_$timestamp.txt" -ea 0 | Remove-Item -ea 0
$logfile=".\CSVandMemory_Report_$timestamp.txt"

"This Report was run at $date " | out-file -filepath $logfile -append
" " | out-file -filepath $logfile -append

function GetCSVFreeSpace {
#incorporated and modified from http://blogs.msdn.com/b/clustering/archive/2010/06/19/10027366.aspx
$objs = @()

$csvs = Get-ClusterSharedVolume -Cluster $Cluster
foreach ( $csv in $csvs )
{
   $csvinfos = $csv | select -Property Name -ExpandProperty SharedVolumeInfo
   foreach ( $csvinfo in $csvinfos )
   {
      $obj = New-Object PSObject -Property @{
         Name        = $csv.Name
         Path        = $csvinfo.FriendlyVolumeName
         Size        = $csvinfo.Partition.Size
         FreeSpace   = $csvinfo.Partition.FreeSpace
         UsedSpace   = $csvinfo.Partition.UsedSpace
         PercentFree = $csvinfo.Partition.PercentFree
      }
      $objs += $obj
   }
}

$objs | ft -auto Name,Path,@{ Label = "Size(GB)" ; Expression = { "{0:N2}" -f ($_.Size/1024/1024/1024) } },@{ Label = "FreeSpace(GB)" ; Expression = { "{0:N2}" -f ($_.FreeSpace/1024/1024/1024) } },@{ Label = "UsedSpace(GB)" ; Expression = { "{0:N2}" -f ($_.UsedSpace/1024/1024/1024) } },@{ Label = "PercentFree" ; Expression = { "{0:N2}" -f ($_.PercentFree) }}
}

function SentReportviaMail {
$logfile=(Get-item ".\CSVandMemory_Report*" -ea 0).Name
$Logs=Get-Content $logfile
$smtpServer = "YOURSMTP"
$smtpFrom = "johndoe@mydomain.com"
$SMTPPort = "25"
$Username = "johndoe@mydomain.com"
$Password = 'YOURPASSWORD'
$smtpTo = "reports@mydomain.com"
$messageSubject = "$VMMServer - Automated CSV FreeSpace and Total Memory Report"

[string]$messagebody = ""

foreach ($log in $logs )
{
	$messagebody = $messagebody + $log + "`r`n"
}
#Write-Host " "
#Write-Host "Starting to sent mail to $smtpTo via $smtpServer ...." -ForegroundColor green
$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$smtp.Credentials = New-Object System.Net.NetworkCredential($Username, $Password);
$smtp.Send($smtpFrom,$smtpTo,$messagesubject,$messagebody)
#Write-Host "mail sent completed " -ForegroundColor green
#Write-Host " "
}


foreach ($Cluster in $VMMClusters)
{
	#Write-Host "Starting to collect memory and CSV free space data in $Cluster ....." -foregroundcolor green
	[int]$TotalFreeMemory = 0;
	[int]$TotalMemory = 0;
	$ClusterNodes = Get-Cluster $Cluster | Get-ClusterNode
	foreach ($ClusterNode in $ClusterNodes)
	{
		[int]$FreeMemory = [math]::round(((Get-WmiObject -ComputerName $ClusterNode -Class Win32_OperatingSystem).FreePhysicalMemory / 1MB), 0)
		[int]$TotalFreeMemory = [int]$TotalFreeMemory + [int]$FreeMemory
		[int]$NodeMemory = [math]::round(((Get-WmiObject -ComputerName $ClusterNode -Class Win32_OperatingSystem).TotalVisibleMemorySize / 1MB), 0)
		[int]$TotalMemory = [int]$TotalMemory + [int]$NodeMemory

	}

	$TotalAvailableMemory = $TotalFreeMemory - $NodeMemory
 
	"Cluster: $Cluster" | out-file -filepath $logfile -append
	"Total Memory: $TotalMemory" | out-file -filepath $logfile -append
	"Total Free Memory: $TotalFreeMemory" | out-file -filepath $logfile -append
	"Total Available Memory: $TotalAvailableMemory" | out-file -filepath $logfile -append
	" " | out-file -filepath $logfile -append
	"CSV Freespace : " | out-file -filepath $logfile -append
	GetCSVFreeSpace | out-file -filepath $logfile -append
	" " | out-file -filepath $logfile -append
}
SentReportviaMail

example output mail:

image

Disclaimer: Please read, understand and test script before you run put in production! This should just give you an idea around the power of powershell and automation

 

Powershell–How to monitor HP Smartarray disk status?

July 4, 2014

really a quick one and straight forward but sometimes very useful. here is a quick example how you can monitor your smartarray controller disk status and in case of “Failed” drive detected sent a mail out to you with the summary.

Of course, SCOM has also automated capabilities to monitor HP hardware components in a much more efficient way but that’s a another story

Prerequisites are:

– depends on your SA version – you need the “HP ProLiant Array Configuration Utility (CLI) for Windows” and can be found here, the user guide here

– if required, modify program path to hp array utility command line tool "C:\Program Files\HP\hpssacli\bin\hpssacli.exe"

– modify smtp settings $smtpServer, $smtpFrom, $SMTPPort, $Username, $Password and $smtpTo

– modify $localhost

– check if your controller is 0 “controller slot=0”

###Code Snippet###

$localhost="PUTYOURSERVERNAMEHERE"
Get-item ".\log.txt" -ea 0 | Remove-Item -ea 0
$logfile=".\log.txt"

function CheckSmartArray {
Write-Host " "
Write-Host "Checking SmartArray on system"$localhost"" -foregroundcolor green
C:\Windows\System32\cmd.exe /c "C:\Program Files\HP\hpssacli\bin\hpssacli.exe" controller slot=0 physicaldrive all show
}

CheckSmartArray | out-file -filepath $logfile -append

function SentDiskDrivefailedviaMail {
$Logs=Get-Content $logfile
$smtpServer = "yoursmtp.server.com"
$smtpFrom = "sender@yourdomain.com"
$SMTPPort = "25"
$Username = "user@yourdomain.com"
$Password = "passwordhere"
$smtpTo = "recipient@yourdomain.com"
$messageSubject = "Disk Drive failed at $localhost"

[string]$messagebody = ""

foreach ($log in $logs )
{
    $messagebody = $messagebody + $log + "`r`n"
}
Write-Host "failed disk detected – starting to sent mail to $smtpTo via $smtpServer …." -ForegroundColor red
$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$smtp.Credentials = New-Object System.Net.NetworkCredential($Username, $Password);
$smtp.Send($smtpFrom,$smtpTo,$messagesubject,$messagebody)
Write-Host "mail sent completed " -ForegroundColor green
Write-Host " "
}

#Check logfile if a "Failed" status can be found, if true send a mail with "SentDiskDrivefailedviaMail" function
[array]$logcontent=gc $logfile
foreach ($line in $logcontent) {
    if ($line -match "Failed") {
    Write-Host " "
    write-host "failed disk found at $localhost " -foregroundcolor red
    write-host "detailed logs can be found $logfile " -foregroundcolor red
    Write-Host " "
    SentDiskDrivefailedviaMail
    }
}

###Code Snippet###

Sample Output from smart array CLI utility “controller slot=0 physicaldrive all show”

image

Disclaimer: Please read and test script before you run in your production!

Powershell-How to easily verify patch level between computers

July 4, 2014

Compare patches between computers? Here is a quick and easy way how you can verify this with Powershell

$node1 = Get-HotFix -ComputerName SERVER1
$node2 = Get-HotFix -ComputerName SERVER2
Compare-Object -ReferenceObject $node1 -DifferenceObject $node2 -Property HotFixID

Example Output:

HotFixID                                                    SideIndicator
——–                                                    ————-
KB2862152                                                   =>
KB2876331                                                   =>
KB2884846                                                   <=
KB2892074                                                   <=
KB2894029                                                   =>

The Compare-Object cmdlet compares two sets of objects. One set of objects is the "reference set," and the other set is the "difference set."

The result of the comparison indicates whether a property value appeared only in the object from the reference set (indicated by the <= symbol), only in the object from the difference set (indicated by the => symbol) or, if the IncludeEqual parameter is specified, in both objects (indicated by the == symbol).

Compare-Object is really powerful, check it out

http://technet.microsoft.com/en-us/library/hh849941.aspx

Powershell – How to get total VM memory overview (dynamic, static and startup memory) per node in a cluster?

June 16, 2014

Host Memory Pressure – I think this is one of the keys (in addition to storage, network, CPU) in performance when running virtualization with dynamic memory and should be monitored. An balance between high density of running VMs on a host and memory calculation/demand is something to consider when managing self service clouds and/or running memory intensive workloads.

Write-host " "
Write-Host " "
$Cluster = Read-Host "Cluster Name "
cls
Write-Host " "
Write-Host "Starting to check VM Memory pressure on $Cluster nodes " -ForegroundColor green
Write-Host " "
Write-Host "Collecting data like nodes, VMs Memory….please be patient" -ForegroundColor green
Write-Host " "
Write-Host " "
$Hostnames=(Get-Cluster $Cluster | Get-ClusterNode).Name
#$Hostname=(Get-VMhost).Name

foreach ($Host1 in $Hostnames) {
[int]$hostmem=@{} | Out-Null
[int]$totalstartupmem=@{} | Out-Null
[int]$totalmaxmem=@{} | Out-Null
[int]$staticmemory=@{} | Out-Null
[int]$overcommited=@{} | Out-Null
[int]$totalramrequired=@{} | Out-Null

$AllVMs=(get-vm -ComputerName $Host1).Name
$Hostmem=(Get-VMhost -ComputerName $Host1).MemoryCapacity / 1024 / 1024 / 1024

foreach ($VM in $AllVMs) {
$CurrentVM=(get-VM $VM -ComputerName "$Host1" | fl *)
if ((Get-VMMemory -vmname $VM -ComputerName "$Host1").DynamicMemoryEnabled -eq "True") {
$memorystartup=(get-vm $VM -ComputerName "$Host1" | select-object MemoryStartup).MemoryStartup /1024 / 1024 / 1024
$MemoryMaximum=(get-vm $VM -ComputerName "$Host1" | select-object MemoryMaximum).memorymaximum /1024 / 1024 / 1024
$totalstartupmem += $memorystartup
$totalmaxmem += $MemoryMaximum
}
else {
$static=(get-vm $VM -ComputerName "$Host1" | select-object MemoryStartup).MemoryStartup /1024 / 1024 / 1024
$staticmemory += $static
}
}
$totalramrequired=$totalstartupmem + $staticmemory

write-host "Summary Report for Host $Host1" -foregroundcolor green
write-host "Total Startupmem for Dynamic VMs $totalstartupmem GB " -foregroundcolor green
write-host "Total Staticmem for Static VMs $staticmemory GB " -foregroundcolor green
write-host "Total minimum RAM (Startup+Static) required $totalramrequired GB " -foregroundcolor yellow
write-host "Total Maxmem for Dynamic VMs $totalmaxmem GB " -foregroundcolor yellow
write-host "Total available memory $Hostmem GB " -foregroundcolor green
if ($totalmaxmem -gt $Hostmem) {Write-Host "$Host1 is overcomitted " -foregroundcolor red}
write-host " "
write-host " "
}

image

This is just one way to get a total summary per node in your Hyper-V cluster and their configured memory demand. It provides a quick view on memory utilization of your Hyper-V nodes. Be creative and modify based on your needs.

Disclaimer: Please read and test script before you run in your production!

Dynamic Memory Pressure Monitoring:

http://blogs.msdn.com/b/virtual_pc_guy/archive/2010/09/01/looking-at-dynamic-memory-performance-counters.aspx

…a “bad” configuration can result in “bad” performance 🙂

Stay tuned…

How to configure Preferred Owners and AutoFailback with Powershell in Failover Cluster?

April 7, 2014

Consider scenario, you “balanced” your VMs across your nodes and you come back in the morning and they are migrated “for whatever reason” to different nodes. But as a typical administrator 😉 you know your workload best and you want to keep them preferred on a targeted node. In case of an unexpected reboot the VMs will get migrated to next available node in your Failover Cluster and goal is as soon as the node is back the VM should automatically fail back = PreferredOwners. 

Here is a quick example where you configure all clustered VM roles in a targeted cluster for preferred owners based on the current owner node. this should only give you an idea how things can be automated very easily with Powershell:

$Cluster = Read-Host "Cluster Name "
$Praefix = Read-Host "Please provide präfix for your clustered VM role names (a.e.SCVMM) "
Write-Host " "
Write-Host "Getting all clustered VM roles and configure Preferred Owners in cluster $Cluster" -ForegroundColor yellow
Write-Host " "
Write-Host " "
$AllClusterGroup = Get-ClusterGroup -Cluster $Cluster -Name $Praefix*

Write-Host "….running loop for all Clustered VMs"
Write-Host " "
Write-Host " "
foreach ($ClusterGroup in $AllClusterGroup)
{
    $ClusterGroupDetails = Get-ClusterGroup -Name "$ClusterGroup"
    Write-Host "Getting current Owner for $ClusterGroup…." -ForegroundColor yellow
    $CurrentOwner = $ClusterGroupDetails.OwnerNode.Name

    Set-ClusterOwnerNode -Group $ClusterGroup $CurrentOwner
    Write-Host "Current owner for VM $ClusterGroup is $CurrentOwner, configure Preferred Owner…done" -ForegroundColor yellow
    #Enable Autofailback
    (Get-ClusterGroup -Name "$ClusterGroup").AutoFailbackType=1
    Write-Host "Enabling Autofailback VM $ClusterGroup…done" -ForegroundColor yellow
    Write-Host " "
}

Disclaimer: Please read and test script before you run in your production, this reconfigures the preferred owner property at all your clustered VM roles in your cluster !!

There are more options how you can control clustered roles, like “AntiAffinityClass” – when a group is moved during failover, anti-affinity affects the algorithm used to determine the destination node. a.e. never run together at same node…

Here are just a few more good resources around failover options in a Failover Cluster:

Preferred Owners in a Cluster
http://blogs.msdn.com/b/clustering/archive/2008/10/14/9000092.aspx

Failover behavior on clusters of three or more nodes
http://support.microsoft.com/kb/299631/en-us

Understanding Hyper-V Virtual Machine (VM) Failover Policies
http://blogs.msdn.com/b/clustering/archive/2010/12/14/10104402.aspx

Modify the Failover Settings for a Clustered Service or Application
http://technet.microsoft.com/en-us/library/cc771809.aspx

Configure Failover and Failback Settings for a Clustered Service or Application
http://technet.microsoft.com/en-us/library/dd197473(v=ws.10).aspx

AntiAffinityClassNames
http://msdn.microsoft.com/en-us/library/aa369651(v=vs.85).aspx

Using Guest Clustering for High Availability
http://technet.microsoft.com/en-us/library/dn440540.aspx

How to use Powershell in Failover Clustering–Part 1

August 5, 2011

Powershell is a really powerful toy for any Windows administrator where tasks need to be automated and or repeated several times.

Here I would like to start an blog series of how to use Powershell in Windows Server Failover Cluster (WSFC) environments.

Let’s start over with some basic commandlet’s to get status of clustered groups, resources and cluster core resources, move groups and soon. Later we will do some advanced operations with Powershell.

The WSFC Powershell (CLI) interface is everywhere available where WSFC feature is installed:

  • Windows Server 2008 R2 (SP1)
    • Full
    • Core (not installed by default)
  • Microsoft Hyper-V Server 2008 R2 (SP1)
  • Remote Server Administration Tools (RSAT) for Windows 7 (SP1)

First of all, you must import the “FailoverCluster” module to get the commandlet’s. To get a list of all available modules you can use:

PS:\ Get-Module -ListAvailable

image

To import the module you need to use “Import-Module” commandlet:

PS:\ Import-Module FailoverClusters

image

YUHUU Smile We have now the full set of all Failover Cluster commandlet’s available, let’s have a look which they are:

PS:\ Get-Command –Module FailoverClusters or Get-Command | findstr Cluster

image

image

As you can see, there are for the most of the GUI actions an cmdlet available, sometimes more. In total there are 69 Failover Cluster specific cmdlet’s which gives you many many *creative* usage ways.

NOTE: A really helpful method with Powershell is the Get-Help cmdlet:
Built-in help:
Get-Help cmdlet -Full
Examples:
Get-Help cmdlet –Examples
Online help (INET connection is required):
Get-Help cmdlet –Online

Let’s start with some easy commandlet to do some basic operations:

How to get a list of all clustered groups via Powershell?

PS:\ Get-ClusterGroup

image

image

As you can see I do have some resources offline. Let’s bring them online

How to bring online a Cluster Group via Powershell?

PS:\ Start-ClusterGroup “GROUPNAME” image

Now, let’s move a group to a different node to balance the workloads in my *test* cluster Smile

How to move a cluster group via Powershell?

PS:\ Move-ClusterGroup “GROUPNAME” –Node “NODENAME”

image

How to get a list of all clustered resources via Powershell?

PS:\ Get-ClusterResource

image

How to get a list of all clustered groups from an node via Powershell?

PS:\ Get-ClusterNode –Name “NODENAME” | Get-ClusterGroup

image

How to get a list of all clustered resources within a cluster group via Powershell?

PS:\  Get-ClusterGroup "GROUPNAME" | Get-ClusterResource

image

How to get more parameters from a clustered disk (resource)?

PS:\ Get-ClusterResource "Cluster Disk 1" | Get-ClusterParameter

image

image

How can I test/validate my cluster via Powershell?

Since R2 you can also validate your cluster via CLI Powershell:

PS:\ Get-Help Test-Cluster

A.e.: PS:\ Test-Cluster –Node Node1,Node2

image

image

A list of all available Test-Cluster scenarios – which can be *in-/excluded*- can you find here:

image

Hope this has opened your interest in more around Powershell for Failover Clustering – stay tuned for more or start with playing with PS…..Winking smile

Some additional reference can you find here:

Mapping Cluster.exe Commands to Windows PowerShell Cmdlets for Failover Clusters
http://technet.microsoft.com/en-us/library/ee619744(WS.10).aspx

PowerShell Quick Reference
http://www.microsoft.com/downloads/details.aspx?FamilyId=DF8ED469-9007-401C-85E7-46649A32D0E0&displaylang=en

Clustering with PowerShell
http://technet.microsoft.com/en-us/library/ee619751(WS.10).aspx

PowerShell for Failover Clustering: Finding the Drive Letter
http://blogs.msdn.com/b/clustering/archive/2009/10/16/9908325.aspx

PowerShell for Failover Clustering: Understanding Error Codes
http://blogs.msdn.com/b/clustering/archive/2010/04/28/10003627.aspx

PowerShell for Failover Clustering: Frequently Asked Questions
http://blogs.msdn.com/b/clustering/archive/2009/05/23/9636665.aspx

Regards

Ramazan Can