Articles

Using PowerShell & WMI to view Cluster File Share Resources

In PowerShell on October 15, 2010 by brwilkinson Tagged: , , ,

One of the main trends that I have in my job is to automate as many of the task I perform on a daily basis as possible.

Automation does not always mean a particular task takes care of itself, sometimes its just the retrieval of the information that can then help in making a human decision.

New tasks come up all the time and searching for the information you need is always the first step. Often this means logging onto servers or remotely accessing servers through GUI tools while you search around of the information.

Once you know where the information is however you can then look at more efficient ways of retrieving it.

This script below will find the Cluster Resources Information given a File Share Name.

The main reason why I use this script is to find the File location where the share is located, which is commonly used for:

  • Restoring Backups
  • Changing Permissions
  • Adding Directories
  • Adding/Adjusting File Quotas

This is necessary since in a Windows Cluster the resources could be across a

  • host of servers
  • host of drives
  • host of mount points

Here are a few ways to run this script

.\Get-ClusterResource.ps1 -Share Users-Home-01 -Cluster MyClusterServer                        
.\Get-ClusterResource.ps1 -Share Users-Home-01                        
.\Get-ClusterResource.ps1 Users-Home-01
This is what the output looks like:

Retrieving Cluster Info . . . MyClusterServer

Name    Server                        Share               Path        
—-        ——                         —–                  —-        
home 1  CLUSSERVENODE-03  users-home-01  N:\Mount123\Folder\home1

Path: \\CLUSSERVENODE-03\N$\Mount123\Folder\home1

 

The script has been created for my environment, I look up the Server name by making a call to the function Get-NodeActiveResource using the Drive Resource Name E.g. “Disk N:”. I do this because I know the Disk will always have that name and the Share Name does not always match the Resource Name used to create the Share E.g. Above the Name is “home 1”, however the Share is “users-home-01”. Secondly I know the Share will always be located on the same server as that Disk, so the look up always works.

Okay here is the script.

#Requires -Version 2.0                                    
[CmdletBinding(DefaultParametersetName="HostList")]                                    
 Param                                     
   (                                               
    [Parameter(Mandatory=$false,                        
               Position=1,                                    
               ParameterSetName="HostList",                                       
               ValueFromPipeline=$false,                                    
               ValueFromPipelineByPropertyName=$false)]                                    
    [Array]$Cluster = "MyClusterServer",                        
    [Parameter(Mandatory=$true,                        
               Position=0,                        
               ParameterSetName="HostList",                        
               ValueFromPipeline=$true)]                        
    [String]$Share                        
   )#End Param                        
                        
Begin                                    
{                                    
 Write-Host "`n Retrieving Cluster Info . . . " -nonewline                                    
}#Begin                                  
Process                                    
{                        
                        
switch ($PsCmdlet.ParameterSetName)                                     
    {                                     
    "HostFile"  {$Servers = (Get-Content $HostFile)}                                     
    "HostList"  {$Servers = $Cluster}                                     
    }                        
$Servers | ForEach-Object {                        
$ClusterServer = $_                        
$ClusterServer | Out-Host                       
                        
function Get-NodeActiveResource($Drive, $ComputerName)                        
    {                        
        # Find the Active Resources                        
        $PartComponent = 'MSCluster_Resource.Name="' + $Drive + '"'                        
        $Filter = "PartComponent = '$PartComponent'"                        
        $Info = get-wmiobject -Filter $Filter -namespace "root\MSCluster" `
        -class "MSCluster_NodeToActiveResource" -ComputerName $ComputerName                        
        if ($Info -ne $Null)                        
            {                        
             $Info | ForEach-Object {                        
                    $Server = ($_.GroupComponent).split("=")[1]                        
                    $Resource = ($_.PartComponent).split("=")[1]                        
                    $Hash = @{                        
                Server=$Server.substring(1, ($Server.length-2))                        
                Resource=$Resource.substring(1, ($Resource.length-2))                        
                }                        
                $ResourceInfo = New-Object PSObject -Property $Hash                        
                $ResourceInfo                        
            }                        
            }                        
    }#Get-NodeActiveResource                        
                        
# Find the Resource Information                        
$Filter2 = "PrivateProperties.ShareName = '$Share'"                        
get-wmiobject -namespace "root\MSCluster" -class "MSCluster_Resource"`
     -ComputerName $ClusterServer -Filter $Filter2 |                         
ForEach-Object {                        
                        
        $Path = $_.PrivateProperties.Path                        
        $PathSplit = $Path.split(":")                        
        $Drive = "Disk " + $PathSplit[0] + ":"                        
        $Server = (Get-NodeActiveResource -Drive $Drive `
                                -Computername $ClusterServer).Server                        
                        
        $Hash2 = @{                        
    Name=$_.Name                        
    Share=$_.PrivateProperties.ShareName                        
    Path=$Path                        
    Server=$Server                        
    }                        
    $ShareInfo = New-Object PSObject -Property $Hash2                        
    $ShareInfo | ft -autosize | Out-Host                        
    $ShareInfo                        
}#ForEach-Object(WMI)                        
                        
}#ForEach-Object(Servers)                        
}#Process                                    
End                                    
{                           
    If ($ShareInfo -ne $Null)                        
    {                        
        $Path = "\\" + $ShareInfo.Server + "\" + $PathSplit[0] `
                                                + "$" + $PathSplit[1]                        
        if ($Path -ne $Null)                        
        {Write-Host "`n Path:" $Path}                        
    }                        
   else                        
    {                        
        Write-Host "`n No share """$Share """ on" $ClusterServer `
                            -BackgroundColor Red -ForegroundColor White                        
    }                        
        # Cleanup Variables, useful during testing to            
        # make sure no false positives                        
        $Servers,$Server,$Resource,$Path,$Hash,$Hash2,$Filter = $Null                        
        $Filter2, $ResourceInfo,$ShareInfo,$PathSplit,$Info = $Null                        
}#End 

Summary Info

The inner function of this script Get-NodeActiveResource is also very useful as a standalone script for finding out which servers resources are hosted on and can be used like below:

.\Get-NodeActiveResource.ps1 "Disk N:"            

 Retrieving Cluster Info . . .
Server                                         Resource                                     
------                                         --------                                     
CLUSSERVENODE-05                               Disk N: 

It is worth noting that I have used Windows Management Instrumentation (WMI) for retrieving this information. Server 2008 R2 Failover Clustering has built in cmdlets that are very useful and I will include a script for setting up the Failover Clustering on Server 2008 R2 from scratch in another post.

Leave a comment