Powershell has a nice set of Cluster cmdlets that make life a little easier when attempting to inventory your clustered environment. Many of these cmdlets can be executed remotely from a server or workstation and use a virtual name but some cmdlets require you to execute them on the cluster or a node.
Let’s take a look at some functional examples and provide a solution to grabbing cluster resources remotely.
Get Cluster Name or All Clusters
In most cases Administrators keep an inventory of servers and SQL Server clusters. There are times when you might want to search the network for everything. The Get-Cluster command will list the virtual names for all of the clusters known in the domain.
Get-Cluster -Domain 'MyDomain'
Once we have the Virtual Cluster name on the network we can remove the -Domain and add the -Name to the command and look at the properties for each one.
Get-Cluster -Name 'MyClusterVirtualName' | format-List -Property *
These properties can then be queried using Select-Object on the pipeline or by wrapping the command in parenthesis.
Get-Cluster -Name 'MyClusterVirtualName' | Select-Object Name, Domain, ClusterLogLevel, RecentEventsResetTime
(Get-Cluster -Name 'MyClusterVirtualName').Name
(Get-Cluster -Name 'MyClusterVirtualName').GroupDependencyTimeout
(Get-Cluster -Name 'MyClusterVirtualName').RecentEventsResetTime
(Get-Cluster -Name 'MyClusterVirtualName').Domain
(Get-Cluster -Name 'MyClusterVirtualName').ClusterLogLevel
In many cases you may have the Resource or Group virtual network name but not the cluster that they are on. Get-Cluster will allow you to retrieve the cluster name using the resources Network Name. This one has been very useful for SQL Server as I usually get only the Network Name and SQL instance from clients.
Get-Cluster -Name 'VirtualGroup01'
Get All Cluster Nodes & Node Resources
Using the cluster virtual network name we can use Get-ClusterNode to find all of the Nodes that the cluster is using.
## Get the cluster nodes and state
Get-ClusterNode -cluster 'MyClusterVirtualName'
## Get just the cluster node names
Get-ClusterNode -cluster 'MyClusterVirtualName' | Select-Object Name
(Get-ClusterNode -cluster 'MyClusterVirtualName').Name
Just like above lets try to squeeze more information out of the properties of in these objects. Add the Node name to the command and look at the properties available to this cmdlet. Then we can use a Select-Object or the parenthesis to display specific details.
Get-ClusterNode -cluster 'MyClusterVirtualName' -Name 'NodeName' | Format-List -Property *
## Get only certain properties
Get-ClusterNode -cluster 'MyClusterVirtualName' -Name 'NodeName' | Select-Object NodeName, BuildNumber, State
(Get-ClusterNode -cluster 'MyClusterVirtualName' -Name 'NodeName').BuildNumber
(Get-ClusterNode -cluster 'MyClusterVirtualName' -Name 'NodeName').State
(Get-ClusterNode -cluster 'MyClusterVirtualName' -Name 'NodeName').Model
Going the other way, we can also provide the Node name to Get-Cluster cmdlet and it will return the Cluster Virtual Name. If we have one we can get the other
Get-Cluster -Name 'NodeName'
(Get-Cluster -Name 'NodeName').Name
Get Cluster Group Details
The next logical progression is to find the Group or Roles that exist on the cluster and their state. I use the Get-ClusterGroup cmdlet often as it tells me in one command the Groups, their Status and what Node they are currently sitting on.
Get-ClusterGroup -cluster 'MyClusterVirtualName'
Get-ClusterGroup -cluster 'MyClusterVirtualName' | Select-Object Name, OwnerNode
(Get-ClusterGroup -cluster 'MyClusterVirtualName').Name
## We can also use the group -Name to see only one result
Get-ClusterGroup -cluster 'MyClusterVirtualName' -Name SQL1234
Get Cluster Resources Remotely Using Invoke-Command
The trouble with some cluster cmdlets is that they must be executed on the cluster locally. Luckily Powershell offers the ability to do this using a cmdlet called “invoke-Command“. We can collect more information on the Cluster resources using these cmdlets.
In this example everything in the -ScriptBlock is executed on the remote cluster and we use Get-ClusterResource because it cannot be executed remotely on its own.
## Get all cluster Resources
Invoke-Command -ComputerName 'MyClusterVirtualName' -ScriptBlock { Get-ClusterResource }
## use the Resource Name to get details
Invoke-Command -ComputerName 'MyClusterVirtualName' -ScriptBlock { Get-ClusterResource -Name Disk001 }
Invoke-Command -ComputerName 'MyClusterVirtualName' -ScriptBlock { Get-ClusterResource -Name 'SQL Server (MSSQL1103)' }
Invoke-Command -ComputerName 'MyClusterVirtualName' -ScriptBlock { Get-ClusterResource -Name 'NetName' }
We can also look at the properties available from Get-ClusterResources.
Invoke-Command -ComputerName 'MyClusterVirtualName' -ScriptBlock { Get-ClusterResource -Name Disk001 | Format-List -Property *}
## Select only certain properties
Invoke-Command -ComputerName 'MyClusterVirtualName' -ScriptBlock { Get-ClusterResource -Name Disk001 }
Invoke-Command -ComputerName 'MyClusterVirtualName' -ScriptBlock { Get-ClusterResource -Name 'SQL Server (MSSQL1103)' } | Select-Object Cluster, Name, RestartDelay }
Use Get-ClusterParameters Remotely
Get-ClusterParameter is another cmdlet that does not let me run it remotely. We can pass it the same way using Invoke-Command and pair it with Get-ClusterResource to get results from our remote Cluster.
## get a list of parameters from a certain cluster resource
Invoke-Command -ComputerName 'MyClusterVirtualName' -ScriptBlock { Get-ClusterResource -Name Disk001 | Get-ClusterParameter }
## Use the list to specify what we really need using -Name
Invoke-Command -ComputerName 'MyClusterVirtualName' -ScriptBlock { Get-ClusterResource -Name 'SQL Server (MSSQL1103)' | Get-ClusterParameter -Name VirtualServerName }
Invoke-Command -ComputerName 'MyClusterVirtualName' -ScriptBlock { Get-ClusterResource -Name Disk001' | Get-ClusterParameter -Name Disk001 | Select-Object DiskSignature }