Microsoft Virtualization Discussions
Microsoft Virtualization Discussions
Hi NetApp Admins, I am new to Netapp powershell and i has this confusion
volumes12.txt contains list of volumes
foreach( $vol in Get-Content ".\volumes12.txt") {
{
Get-NcVol $vol -Verbose
Set-Ncvol $vol
}
None of the above commands seems to work,
whereas if i do this through an array it works.
$volumelist = get-ncvol -Name *sqlvol1* | Select-Object $_.Volume
ForEach ($vol in $volumelist)
{
Set-NcVol $vol -Offline -Verbose
}
at present i have lots of offline volumes in a text file, i want to to remove/destroy the volumes by reading that file
Solved! See The Solution
The first error you're getting is because the value of $filename is invalid. The value of the $filename variable should be either a canonical or relative path + filename for the text file which contains the volume names. For example, here's how I generated my test volume list:
# get 10 random, volumes which are not node or SVM root volumes
$volumes = Get-NcVserver $svmName | Get-NcVol -Attributes @{} -Query @{ VolumeStateAttributes = @{ IsNodeRoot = $false; IsVserverRoot = $false } } | Get-Random -Count 10 | Select-Object -ExpandProperty Name | Out-File ./volumes.txt $volumes | Out-File "C:\Users\asulliva\Documents\volumes.txt"
The result looks like this:
From there, I simply execute the code from above:
Get-Content ./volumes.txt | %{ Get-NcVol -Vserver $svmName -Name $_.Trim() }
Resulting in...
The second "error", or rather lack of correct output, is because you aren't using the trim function on the string being read from the file.
Andrew
All those cmdlets take pipeline input
so for example
get-ncvol -Name *sqlvol1 | set-ncvol -offline | remove-ncvol -confirm:$false
Your code doesn't work below and is confusing.. The above line will do the trick, and you don't need the vols in a file if you know the pattern
If you have the vols in a file like this
$vols = gc filenameofvols.txt
connect-nccontroller $controller -cred $cred
$vols | % {
get-ncvol $_ | set-ncvol -offline | remove-ncvol -confirm:$false
}
Hi @SaravanaPandi,
Can you elaborate on what you're trying to do with the volumes? It appears that you're issuing the Set-NcVol cmdlet with no options beyond the volume name, which won't result in any action.
Beyond that, as @JGPSHNTAP mentioned, there are some things you can do to optimize the code and/or make it more PowerShell-like. The pipeline is super helpful for these types of operations...
Also, you'll want to make sure to specify the SVM name when querying the cluster for volumes. The SVM is like a namespace, so it's possible to have multiple volumes that have the same name in different SVMs. Using the cmdlet with just the volume name would return all instances.
Andrew
@JGPSHNTAP@asulliva - I skipped the setting up the svm part, its not possible to offline the volume unless we specify svm or set the svm property in the current controller context.
I wanted to do the offline the volumes the first day, and store the same offline volumes(which i did manually) in a text file(as backup, recording purposes) and remove the same volumes few days later from the file(offline volumes) as input.
Pipeline commands will be useful, but it will destroy the volume, and its difficult to get the volume back,
It looks like a long process instead of simple one, but incase, we offlined one of the volumes incorrectly, just in case few days we can simply enable the volume back.
The reason is i may have 20 offline(which i did) volumes in the first day , may have 30 offline volumes(another storage admin might have offlined 10 more volumes) in the thirdday. wanted to destory only the 20 volumes volumes which i did offline, not someone else even if its a same pattern. That's why i wanted to use file as input
$vols1 = gc ".\volumes15.txt"
$vols1 | % {get-ncvol $_}
or $vols1 = gc ".\volumes15.txt" foreach ($vol in $vols1) { get-ncvol $vol}
gives the same result, its reads only the end of the file, for example if i have 3 volumes its acts only on the the last line/3rd volume
$vols1 = gc ".\volumes15.txt"
$vols1 | % {get-ncvol $_}
or $vols1 = gc ".\volumes15.txt" foreach ($vol in $vols1) { get-ncvol $vol}
gives the same result, its reads only the end of the file, for example if i have 3 volumes its acts only on the the last line/3rd volume
^^
That's impossible. Post your file
Thanks for your followup
Import-Module Dataontap
$ctrl = Read-Host -Prompt "Please enter your controller name!"
Connect-NcController $ctrl
$svm= Read-Host -Prompt "Please enter your svm!"
$global:CurrentNcController.Vserver = $svm
$vols12 = gc ".\volumes15.txt"
ForEach ($vol1 in $vols12)
{
#Ignore the errors
#Write-Host $vol1
Get-NcVol -Name $vol1 -verbose -> This one did not show any error.or output
# Set-NcVol $vol1 -Offline -Confirm -> Tried this one. apparently it looks like the ncvol commands have difficult in parsing the volumes one by one.
write-host $vol1 -> Displays the volumes properly.
}
Volumes in the text file.
ora_sample_log_08232017
ora_sample_log_08242017
ora_sample_log_08252017
Below is the error for Set-Ncvol ,
Set-NcVol : Invalid character ' ' in volume name. It can have '_' and alphanumeric characters.
+ Set-NcVol $vol1 -Offline -Confirm
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: [Set-NcVol], EAPIERROR
+ FullyQualifiedErrorId : ApiException,DataONTAP.C.PowerShell.SDK.Cmdlets.Volume.SetNcVol
Getting the same error for toolkit version 4.2 and 4.3 as well.
It seems that the Get-Content cmdlet is padding out each line to be the same length which is what's causing them to not work when iterating over the values in the resulting array. This works for me:
Get-Content $filename | %{ Get-NcVol -Vserver $svmName -Name ($_.Trim()) }
I simply added the ".Trim()" function call to the string object.
Hope that helps.
Andrew
@asulliva Thats true. i opened the file in a spread sheet and saved again as a msdos file, it worked once. Again the get-content cmdlet didn't work.
Get-Content : Cannot bind argument to parameter 'Path' because it is an empty string.
At line:3 char:13
+ Get-Content $filename | %{
+ ~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Get-Content], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Microsoft.PowerShell.Commands.GetContentCommand
$filename contains $filename = Get-Content .\volumes.txt, its a simple text file with two volumes listed one by one
throws above error if i tried the script mentioned by you.
I tried like below.
$volumes = get-content .\volumes1.txt (original file volumes.txt)
ForEach ($vol in $volumes)
{
Get-NcVol $vol -verbose
}
volumes.txt has 70 kb( 2 volume names) open this in a excel save as in msdos text file and save it as volumes1.txt, the file size changes. also the get-ncvol reads only 2 lines in the text file volumes1.txt as it supposed to.
where as if i keep the volumes.txt as input it reads the two lines as well displays all volumes like a plain get-ncvol
The first error you're getting is because the value of $filename is invalid. The value of the $filename variable should be either a canonical or relative path + filename for the text file which contains the volume names. For example, here's how I generated my test volume list:
# get 10 random, volumes which are not node or SVM root volumes
$volumes = Get-NcVserver $svmName | Get-NcVol -Attributes @{} -Query @{ VolumeStateAttributes = @{ IsNodeRoot = $false; IsVserverRoot = $false } } | Get-Random -Count 10 | Select-Object -ExpandProperty Name | Out-File ./volumes.txt $volumes | Out-File "C:\Users\asulliva\Documents\volumes.txt"
The result looks like this:
From there, I simply execute the code from above:
Get-Content ./volumes.txt | %{ Get-NcVol -Vserver $svmName -Name $_.Trim() }
Resulting in...
The second "error", or rather lack of correct output, is because you aren't using the trim function on the string being read from the file.
Andrew
@asulliva Thank you , thanks for the hashtable example, was using Initialize-NcObjectProperty
In Ontap 9, destroying a volume isn't that bad anymore. They have created a recovery que. We adjust all our SVM's to 168hours, and we don't purge the recovery queue unless we are doing testing.
I would look into that because you are doing lots of extra work.
Also, powershell is super flexible, you can code whatever you want and how you want...