The following
is a PowerShell Module I wrote to help manage multiple cDOT Clusters.
Save the
script as Multi-NcCmdlets.psm1 into:
C:\Users\{USERNAME}\Documents\WindowsPowerShell\Modules\Multi-NcCmdlets
Then in
PowerShell run:
Import-Module
Multi-NcCmdlets -DisableNameChecking
Note: DisableNameChecking is only there because
PowerShell likes verbs at the start of cmdlet names, and complains if you don’t
use this convention.
You’ll
need a text file with all the Cluster IPs/DNS entries in, then run these
cmdlets -
Multi-NcClusters-Load
Multi-NcCredentials-Add
Multi-NcControllers-Connect
- and then
we can manage multiple clusters with PowerShell with single commands!
There is
a help output:
Multi-Help
And an example
of something we can do -
Multi-Set-NcUserPassword-AdminSVM
- which allows
changing a password for a user in the Admin SVM, across all connected clusters.
Time
permitting, I’ll expand the list.
Note: The DataONTAP PowerShell Toolkit is a
requirement.
The Script
###########################
## PART 1: Multi-Nc Core ##
###########################
Function Multi-Help{
[Void](Multi-NcCmdlets) }
Function Multi-NcCmdlets{
Wr; Wr "+++++ Multi-NcCmdlets
+++++" MAGENTA; Wr
Wr; Wr "A selection of cmdlets to manage
multiple clusters in one go!" CYAN; Wr
Wr; Wr "1 " CYAN; Wr
"Multi-NcClusters-Load" YELLOW; Wr ' ==> creates the $Global
variable $NcClusterNames' GREEN
Wr; Wr "2 " CYAN; Wr
"Multi-NcCredentials-Add" YELLOW
Wr; Wr "- " CYAN; Wr "Multi-NcCredentials-Remove"
YELLOW
Wr; Wr "3 " CYAN; Wr
"Multi-NcControllers-Connect" YELLOW; Wr ' ==> creates the $Global
variable $NcConnectedControllers' GREEN
Wr; Wr "- " CYAN; Wr
"Multi-NcControllers-Release" YELLOW; Wr
Wr; Wr "Run 1 -> 2 -> 3, then
we're ready to use Multi-* comdlets!" CYAN; Wr
Wr; Wr "X " CYAN; Wr
"Multi-Set-NcUserPassword-AdminSVM" YELLOW; Wr; Wr
}
Function
Multi-NcClusters-Load {
Param([String]$File)
If(!(Get-Module DataONTAP)){
[Void](Import-Module DataONTAP -ErrorAction
SilentlyContinue)
If( !(Get-Module DataONTAP) ){ Wr; Wr
"Unable to load PSTK!" RED; Wr; Wr; RETURN }
}
Wr; Wr "PSTK loaded ..." GREEN; Wr
Wr; Wr "Loading file containing cluster
management IPs/Name ..." CYAN; Wr; Wr
[String]$File = PromptValidator -Prompt
"Enter Filename/Filepath" -PreAnswer $File
If(Test-Path $File){
[System.Array]$FileContent = Get-Content $File }
Else{ Wr; Wr "Failed to load
$File!" RED; Wr; Wr; RETURN }
If($FileContent.count -eq 0){ Wr; Wr "No
content in $File!" RED; Wr; Wr; RETURN }
[System.Array]$Global:NcClusterNames = @()
Foreach ($Line in $FileContent){
$Line = $Line.Trim("`t","
")
If( !$Line.StartsWith("#") -and
($Line -ne "") ){
$Global:NcClusterNames += $Line.Split("#")[0].Trim("`t","
")
}
}
If($Global:NcClusterNames.count -eq 0){ Wr;
Wr "No valid content in $File!" RED; Wr; Wr; RETURN }
Wr; Wr "Loaded $File ..." GREEN; Wr
Wr; Wr 'PS> $NcClusterNames' CYAN; Wr; Wr
$Global:NcClusterNames; Wr
}
Function
Multi-NcCredentials-Remove{ [Void](Multi-NcCredentials-Add -Remove) }
Function
Multi-NcCredentials-Add{
Param([Switch]$Remove)
If(!$Global:NcClusterNames){ Wr; Wr 'No
$NcClusterNames - run Multi-NcClusters-Load!' RED; Wr; Wr; RETURN }
If(!$Remove){ Wr; Wr 'Note: If there are
existing stored NcCredentials for $NcClusterNames, they will be overwritten
(can use Get-NcCredential to check)!' YELLOW; Wr; Wr }
If(!$Remove){ [String]$UserName =
PromptValidator -Prompt "Enter Username" }
If(!$Remove){ Wr "Enter Password:"
CYAN; $Password = Read-Host -AsSecureString }
If(!$Remove){ $Credentials = New-Object
System.Management.Automation.PsCredential($Username,$Password) }
If(!$Remove){ $Global:NcClusterNames |
Foreach{ [Void](Add-NcCredential -Controller $_ -Credential $Credentials) } }
else{ $Global:NcClusterNames | Foreach{
[Void](Remove-NcCredential -Name $_ -ErrorAction SilentlyContinue) } }
Wr; Wr "PS>
(Get-NcCredential).Name" CYAN; Wr; Wr
(Get-NcCredential).Name; Wr
}
Function Multi-NcControllers-Connect{
If(!$Global:NcClusterNames){ Wr; Wr 'No
$NcClusterNames - run Multi-NcClusters-Load!' RED; Wr; Wr; RETURN }
[System.Array]$Global:NcConnectedControllers
= @(); Wr
Foreach($Controller in
$Global:NcClusterNames){
If( !(Get-NcCredential -Name $Controller)
){ Wr "No credentials for $Controller - run Multi-NcCredentials-Add!"
RED; Wr }
Else{
$ConnectNcController =
Connect-NcController -Name $Controller -Timeout 15000 -ErrorAction
SilentlyContinue
If($ConnectNcController){
$Global:NcConnectedControllers += $Controller }
If($ConnectNcController){ Wr
"Connected to $Controller!" GREEN; Wr }
Else{ Wr "Unable to connect to
$Controller!" RED; Wr }
}
}
$Global:CurrentNcController = $null
Foreach($Controller in
$Global:NcConnectedControllers){
[Void](Connect-NcController -Name
$Controller -Add -Timeout 15000 -ErrorAction SilentlyContinue)
}
Wr; Wr 'Connected to all
$NcConnectedControllers below:' GREEN; Wr
Wr 'PS> $CurrentNcController' CYAN; Wr
$Global:CurrentNcController
}
Function
Multi-NcControllers-Release{
[System.Array]$Global:NcConnectedControllers
= @()
$Global:CurrentNcController = $null
}
Function
Verify-NcConnectedControllers{
If(!$Global:NcConnectedControllers){ Wr; Wr
'No $NcConnectedControllers - run Multi-NcControllers-Connect!' RED; Wr; Wr;
RETURN $FALSE }
[System.Array]$GlobalCurrentNccontrollerNames
= ($Global:CurrentNcController).Name
Foreach($Controller in
$Global:NcConnectedControllers){
If( !($GlobalCurrentNccontrollerNames
-Contains $Controller) ){
Wr; Wr 'Mismatch of $CurrentNcController
v $NcConnectedControllers - re-run Multi-NcControllers-Connect!' RED; Wr; Wr;
RETURN $FALSE
}
}
RETURN $TRUE
}
Function Wr{
Param([String]$Echo,[String]$Ink =
"WHITE")
If($Echo){ Write-Host $Echo -ForegroundColor
$Ink -NoNewLine }
Else { Write-Host }
}
Function PromptValidator{
Param([String]$Prompt,[System.Array]$Answers,[String]$PreAnswer,[Switch]$CaseSensitive,[Switch]$AllowCR)
While ($true){
Wr ($Prompt + ":") CYAN
If($PreAnswer){ Wr $PreAnswer; Wr; RETURN
$PreAnswer }
else{ $ReadIn = Read-Host }
If($Answers -and $CaseSensitive){ Foreach ($a in $Answers){
If($ReadIn -ceq $a){ RETURN $ReadIn } } }
If($Answers -and !$CaseSensitive){ Foreach
($a in $Answers){ If($ReadIn -eq $a){
RETURN $ReadIn } } }
If(!$Answers -and ($ReadIn.length -gt 0) ){
RETURN $ReadIn }
If($AllowCR
-and ($ReadIn.length -eq 0) ){ RETURN "" }
}
}
##############################
## PART 2: Multi-Nc Add Ons
##
##############################
Function
Multi-Set-NcUserPassword-AdminSVM{
If( !(Verify-NcConnectedControllers) ){
RETURN }; Wr
[String]$UserName = PromptValidator -Prompt
"Enter user whose password is to be reset"
Wr "Enter new password:" CYAN;
$Password = Read-Host -AsSecureString
$NewCred = New-Object
System.Management.Automation.PsCredential($UserName,$Password)
$VsAttrs = Get-NcVserver -Template
$VsQuery = Get-NcVserver -Template
$VsQuery.VserverType = "admin"; Wr
$Global:CurrentNcController | Foreach {
$_.Vserver = (Get-NcVserver -Query $VsQuery
-Attributes $VsAttrs -Controller $_)
[System.Array]$GetUser = Get-NcUser -Name
$Username -Controller $_ -ErrorAction SilentlyContinue
If(!$GetUser){ Wr ("User $UserName
does not exist on " + $_.Name + ":" + $_.Vserver +
"!") RED; Wr }
elseif($GetUser[0].AuthMethod -ne
"password"){ Wr ("User $UserName is not password authenticated
on " + $_.Name + ":" + $_.Vserver + "!") RED; Wr }
else{
[Void](Set-NcUserPassword -Credential
$NewCred -Controller $_)
Wr ("Ran Set-NcUserPassword for user
$UserName on " + $_.Name + ":" + $_.Vserver + "!")
GREEN; Wr
}
}; Wr
}
Comments
Post a Comment