Microsoft Virtualization Discussions

Adding all volumes on filer to an array


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

$totalsnapsize = 0
get-NAVol | %{
Write-Host $_.Name -ForegroundColor Green
Get-NaSnapshot $_.Name | %{If ($_.Total -gt 1000000) {Write-Host $ ([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 . . .