Microsoft Virtualization Discussions
Microsoft Virtualization Discussions
I am trying to update the snapshot schedules on a large number of filers using a PowerShell script. Each of the filers has a number of standard volumes that include the location of the filer example; volume1xx, volume2xx, volume3xx, where xx would be the location of the filer.
My thought is that I could someone use a "(Get-NaVol | where {$_.Name -contains $location})" type command to populate an array with all of the volumes on a particular filer and then run each of the volumes in the array into the Set-NaSnapshotSchedule command.
Has anyone done this before, or possibly have input into accomplishing getting the array populated with the volumes.
Otherwise, has anyone performed a similar operation with a different process that they can share?
Thanks in advance.
I would handle this with the following code:
#If $netAppCred equals $null, get credentials
if ($netappCred -eq $null) {
$netappCred = Get-Credential -Credential "root"
}
# Create array of Filer names
$filerNames = @("filer1", "filer2", "filer3")
# Create array for all volumes
$allVols = @()
# Connect to each NetApp filer
# Get volumes from each Netapp filer
# Sort the volumes by name
# Add the "Filer" property
# Add the volume array to $allVols
foreach ($filerName in $filerNames) {
#Connect to NetApp filer
$netapp = Connect-NaController -Name $filerName -Credential $netappCred
# Get volumes and sort by volume name
$vols = Get-NaVol | Sort-Object -Property "Name"
# Add filer name as a property named "Filer"
$vols | Add-Member -MemberType NoteProperty -Name "Filer" -Value $filerName
# Add $vols to $allVols
$allVols += $vols
}
This will give you an array of volume objects with an added property named "Filer".
Lance, you may not even need to save the volumes to an array. Use wildcards and the pipeline instead, with something like this inside the "foreach $filerName" loop:
$pattern = "volume*" + $filerName
Get-NaVol $pattern | Set-NaSnapshotSchedule <args>
If Get-NaVol returned more than one object, this would raise an exception.
Something simple like
Get-NaVol | Write-Host $_.Name
gets me:
At line:1 char:23
+ Get-NaVol | Write-Host <<<< $_.Name
+ CategoryInfo : InvalidArgument: (NetApp.Ontapi.Filer.Volume.VolumeInfo:PSObject) [Write-Host], ParameterBindingException
+ FullyQualifiedErrorId : InputObjectNotBound,Microsoft.PowerShell.Commands.WriteHostCommand
Write-Host : The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or th
e input and its properties do not match any of the parameters that take pipeline input.
But, change that to use the %{pscommands_in_a_for_each} construct, then it works, such as:
Get-NaVol | %{Write-Host $_.Name}
An example of this would be something I did today to find the total size of snapshots on a filer that are more than 1GB
connect-nacontroller
$totalsnapsize = 0
get-NAVol | %{
Write-Host $_.Name -ForegroundColor Green
Get-NaSnapshot $_.Name | %{If ($_.Total -gt 1000000) {Write-Host $_.name ([Math]::Round(([Int64]$_.Total / 1MB),2))GB}$totalsnapsize += $_.Total}
}
Write-Host -ForegroundColor Blue Total Large Snapshots is ([Math]::round(($totalsnapsize / 1MB),2)) GB
Note I use the ${ } twice in that block of code, once for getting the volumes, then another once I pull each snap from the current volume.
So, to do a setting change to every volume on every filer, you'd get have to walk that one level up and %{ } the filer array list and then set your desired changes to each volume.
Hi, rnrepp, thanks for posting.
The exception you reported is caused by using the $_ special variable outside of a script block. The snippet I posted does, in fact, work for any number of volumes in the pipeline.
PS C:\> $pattern = "vol*clone"
PS C:\> Get-NaVol $pattern | Set-NaSnapshotSchedule -Weeks 1 -Hours 2 -WhichHours "0,12"
Name State TotalSize Used Available Dedupe FilesUsed FilesTotal Aggregate
---- ----- --------- ---- --------- ------ --------- ---------- ---------
vol1clone online 16.0 GB 5% 15.2 GB True 142 623k aggr1
vol2clone online 180.0 GB 46% 97.3 GB True 214 6M aggr1
PS C:\> Get-NaVol $pattern | Get-NaSnapshotSchedule
Volume Weeks Days Hours Minutes WhichHours WhichMinutes
------ ----- ---- ----- ------- ---------- ------------
vol1clone 1 1 2 0 0,12
vol2clone 1 1 2 0 0,12
The Where-Object cmdlet (aliased to ?) and the ForEach-Object cmdlet (aliased to %) both operate on script blocks, which is why they can use the $_ variable.
Alright, now it makes more sense to me. If only powershell had thrown that as the error description . . .