- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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".
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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>
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Alright, now it makes more sense to me. If only powershell had thrown that as the error description . . .