#requires -version 2.0 function New-NaServer { <# .Synopsis Create a new NAServer object .Description The NaServer object is required to perform any actions against a filer. .Parameter Filer Server (IP, Name, FQN of target Filer) .Parameter Credential PSCredentials to use when connecting via HTTP/HTTPS .Parameter vfiler Vfiler name if applicable .Parameter NOSSL If provided then use HTTP when connecting to the filer. .Parameter Version If provided then use the provided version. If none is provided then use 1.0. .Example New-NaServer -Server "Toaster1" -Credential (Get-Credential) Will Connect via HTTPS to Toaster1 .Example New-NaServer -Server "Toaster1" Will connect via RPC using the credentials of the current console to Toaster1. .Example New-NaServer -Server "Toaster1" -vFiler "v1_Toaster1" -NOSSL Will Connect via HTTP to the vFiler v1_Toaster running on Toaster1. .Outputs Netapp.Manage.NaServer .Link Connect-NaServer Disconnect-NaServer #> [CmdletBinding(SupportsShouldProcess=$false,SupportsTransactions=$False,ConfirmImpact="None",DefaultParameterSetName="RPC")] Param( [Parameter(Mandatory = $true,Position = 0,ValueFromPipelineByPropertyName = $true, ParameterSetName="HTTP", HelpMessage = "The name of the Netapp Filer to connect to.")] [Parameter(Mandatory = $true,Position = 0,ValueFromPipelineByPropertyName = $true, ParameterSetName="RPC",HelpMessage = "The name of the Netapp Filer to connect to.")] [string] $Filer, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true, HelpMessage = "The name of the Netapp vFiler to tunnel to.")] [string] $vFiler, [Parameter(Mandatory = $true,ValueFromPipelineByPropertyName = $true,ParameterSetName = "HTTP",HelpMessage = "PSCredentials to connect to the filer with")] [Management.Automation.PSCredential] $Credential, [Parameter(Mandatory = $false,ParameterSetName = "RPC")] [Switch] $RPC, [Parameter(Mandatory = $false,ParameterSetName = "HTTP")] [Switch] $NoSSL ) Process{ #Determine if were going to tunnel to a vFiler or not. if (!$vFiler){ $S = New-Object NetApp.SDK.NaServer($filer, 1,0) $ServerName = $filer } else{ $S = New-Object NetApp.SDK.NaServer($filer, 1,7) $S.SetVfilerTunneling($vFiler) $ServerName = ("{0}@{1}" -f $vFiler, $filer) } switch ($PScmdlet.parameterSetName) { "HTTP" { #if http then we'll be using username password so set that now $s.Style = "LOGIN_PASSWORD" if ($NoSSL){ $s.TransportType = "HTTP" } else{ $s.TransportType = "HTTPS" } $private:user = $credential.GetNetworkCredential().UserName $private:pwd = $credential.GetNetworkCredential().Password $s.SetAdminUser($private:user, $private:pwd) } "RPC" { $s.Style = "RPC" } } try { $S.Version=([xml]$s.Invoke("system-get-ontapi-version")).results|%{[double]('{0}.{1}' -f $_."major-version",$_."minor-version")} $S.OnTap = $s.Invoke("system-get-version").GetChildContent("version") } catch [NetApp.Manage.NaAuthException] { write-warning $_.Exception.message $s = $null } catch [NetApp.Manage.NaApiFailedException] { if ($_.Exception.GetBaseException().ErrorNo -eq 13011){ Write-Warning $_.Exception.GetBaseException().message $s = $null } else{ throw $_ } } finally{ Write-Output $s } } } function Connect-NaServer{ <# .Synopsis Create persistent connection to a NetApp Filer .Description Create persistent connection to a NetApp Filer This connection is stored in the form of a globaly scoped variable $DefaultNaServer. .Parameter Filer Server (IP, Name, FQN of target Filer) .Parameter Credential PSCredentials to use when connecting via HTTP/HTTPS .Parameter vfiler Vfiler name if applicable .Parameter NOSSL If provided then use HTTP when connecting to the filer. .Parameter Version If provided then use the provided version. If none is provided then use 1.0. .Example New-NaServer -Server "Toaster1" -Credential (Get-Credential) Will Connect via HTTPS to Toaster1 .Example New-NaServer -Server "Toaster1" Will connect via RPC using the credentials of the current console to Toaster1. .Example New-NaServer -Server "Toaster1" -vFiler "v1_Toaster1" -NOSSL Will Connect via HTTP to the vFiler v1_Toaster running on Toaster1. .Outputs Netapp.Manage.NaServer .Link Connect-NaServer Disconnect-NaServer #> [CmdletBinding(SupportsShouldProcess=$false,SupportsTransactions=$False,ConfirmImpact="None",DefaultParameterSetName="RPC")] Param( [Parameter(Mandatory = $true,Position = 0,ValueFromPipelineByPropertyName = $true, ParameterSetName="HTTP", HelpMessage = "The name of the Netapp Filer to connect to.")] [Parameter(Mandatory = $true,Position = 0,ValueFromPipelineByPropertyName = $true, ParameterSetName="RPC",HelpMessage = "The name of the Netapp Filer to connect to.")] [string] $Filer, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true, HelpMessage = "The name of the Netapp vFiler to tunnel to.")] [string] $vFiler, [Parameter(Mandatory = $true,ValueFromPipelineByPropertyName = $true,ParameterSetName = "HTTP",HelpMessage = "PSCredentials to connect to the filer with")] [Management.Automation.PSCredential] $Credential, [Parameter(Mandatory = $false,ParameterSetName = "RPC")] [Switch] $RPC, [Parameter(Mandatory = $false,ParameterSetName = "HTTP")] [Switch] $NoSSL ) Process{ #Determine if were going to tunnel to a vFiler or not. if (!$vFiler){ $S = New-Object NetApp.SDK.NaServer($filer, 1,0) $ServerName = $filer } else{ $S = New-Object NetApp.SDK.NaServer($filer, 1,7) $S.SetVfilerTunneling($vFiler) $ServerName = ("{0}@{1}" -f $vFiler, $filer) } switch ($PScmdlet.parameterSetName) { "HTTP" { #if http then we'll be using username password so set that now $s.Style = "LOGIN_PASSWORD" if ($NoSSL){ $s.TransportType = "HTTP" } else{ $s.TransportType = "HTTPS" } $private:user = $credential.GetNetworkCredential().UserName $private:pwd = $credential.GetNetworkCredential().Password $s.SetAdminUser($private:user, $private:pwd) } "RPC" { $s.Style = "RPC" } } try { $S.Version=([xml]$s.Invoke("system-get-ontapi-version")).results|%{[double]('{0}.{1}' -f $_."major-version",$_."minor-version")} $S.OnTap = $s.Invoke("system-get-version").GetChildContent("version") } catch [NetApp.Manage.NaAuthException] { write-warning $_.Exception.message $s = $null } catch [NetApp.Manage.NaApiFailedException] { if ($_.Exception.GetBaseException().ErrorNo -eq 13011){ Write-Warning $_.Exception.GetBaseException().message $s = $null } else{ throw $_ } } finally { New-Variable -Name DefaultNaServer -scope Global -Value $s -Force } } } Function Disconnect-NaServer { <# .Synopsis Destroy an existing persistant NAServer object .Description Destroy an existing persistant [NaServer] object used to call OnTAPI. .Example Disconnect from the existing NaServer PS > Disconnect-NaServer .Link New-NaServer Connect-NaServer #> [CmdletBinding(SupportsShouldProcess=$true,SupportsTransactions=$False,ConfirmImpact="low",DefaultParameterSetName="")] Param() Process { if (($pscmdlet.ShouldProcess($global:DefaultNaServer.Server, "Disconnect from Filer"))) { Remove-Variable -name DefaultNaServer -scope Global -force } } } Function Get-NaServer { <# .Synopsis Get's the current Filer Connection if none is found then create one. .Example Get-NaServer .Link New-NaServer Connect-NaServer Disconnect-NaServer #> [CmdletBinding(SupportsShouldProcess=$false,SupportsTransactions=$False,ConfirmImpact="low",DefaultParameterSetName="")] Param() Process { if (!$global:DefaultNaServer){ write-warning "@ Target Filer could not be found. To avoid this error: 1.) Pass the -server parameter 2.) create a persistent connection with the Connect-NaServer cmdlet. We will now attempt to create a one time connection for you. @" Return New-NaServer } else { return $global:DefaultNaServer } } } Function Get-NaResult { <# .Synopsis Depreciated... provided for backward compatability .Parameter Request New-Object NetApp.SDK.NaRequest -ArgumentList @("system-get-version") .Parameter Server NaServer to query #> [CmdletBinding(SupportsShouldProcess=$True,SupportsTransactions=$False,ConfirmImpact="None",DefaultParameterSetName="")] param ( [Parameter(Position=0,Mandatory=$TRUE,ValueFromPipeline=$True)] [NetApp.SDK.NaRequest] $request, [Parameter(Position=1,HelpMessage="[NAServer]NAserver (New-NAServer)",ValueFromPipeline=$True)] [NetApp.SDK.NAServer] $server ) process { return ([xml]$server.InvokeElem($request)).results } } Function Get-NaSystemOnTAPIVersion { <# .Synopsis Returns the current OnTAPI version of the server. .Description Returns the current OnTAPI version of the server. .Parameter Server NaServer to query .Example # retrieve the supported ONTAP API version. PS > $server = New-NaServer -filer "TOASTER" -credentials (Get-Credential) PS > Get-NaSystemOnTAPIVersion -server $server 1.7 .Example PS > $server = New-NaServer -filer "TOASTER" -credentials (Get-Credential) PS > $server.Version = Get-NaSystemOnTAPIVersion -server $server .Outputs system.string .Notes #> [CmdletBinding(SupportsShouldProcess=$FALSE,SupportsTransactions=$False,ConfirmImpact="None",DefaultParameterSetName="")] param ( [Parameter(Position=0,HelpMessage="NAserver (New-NAServer)")] [NetApp.SDK.NaServer] $server = (Get-NaServer) ) $request = New-Object Netapp.Manage.NaElement -ArgumentList @("system-get-ontapi-version") $result = ([xml]$server.InvokeElem($request)).results return ("{0}.{1}" -f $result."major-version",$result."minor-version") } Function Get-NaAPI { [CmdletBinding(SupportsShouldProcess=$FALSE,SupportsTransactions=$False,ConfirmImpact="None",DefaultParameterSetName="")] Param( [Parameter(Position=0)] [string] $Name, [Parameter(Position=1,HelpMessage="NAserver (New-NAServer)")] [NetApp.SDK.NaServer] $server = (Get-NaServer) ) Begin { $APIList = @() } Process { $NaElement = New-Object Netapp.Manage.NaElement("system-api-list") $apis = $Server.InvokeElem($naelement).GetChildByName("apis") Foreach ($api in $apis.GetChildren()) { $APIList += $api.getchildcontent("name") } } End { if ($Name){ return $APIList | Where-Object {$_ -match $name} } else{ return $APIList } } } Function Get-NaAPIElements { Param( [NetApp.SDK.NaServer]$server = (Get-NaServer), [string[]]$API, [switch]$Output ) Process{ $e = New-Object NetApp.Manage.NaElement("api-list") Foreach ($A in $API){ $e.AddNewChild('api-list-info',$A) } $NaElement = New-Object NetApp.Manage.NaElement("system-api-get-elements") $NaElement.AddChildElement($e) $apilist = $Server.InvokeElem($naelement).getchildbyname("api-entries") Foreach ($A in $apiList.getchildbyname("system-api-entry-info")){ $Obj = "" | Select API, ElementName, ElementType, Optional, AllowNull $N = $A.GetChildContent("name") foreach ($e in $a.getchildbyname("api-elements").getchildren()){ $obj.API = $N $obj.ElementName = $e.getchildcontent('name') switch ($e.getchildcontent('type')) { "string" {$obj.ElementType = "String"} "integer" {$obj.ElementType = "int"} "boolean" {$obj.ElementType = "Bool"} Default { $obj.ElementType = $_ $objElem = $true } } IF (!$e.getchildbyname('is-optional')){ $Obj.Optional = $False } Else{ $Obj.Optional = $true } IF (!$e.getchildbyname('is-output')){ $objOutput = $False } Else{ $objOutput = $true } IF (!$e.getchildbyname('is-optional')){ $Obj.Optional = $False } Else{ $Obj.Optional = $true } IF ( (!$e.getchildbyname('is-nonempty')) -or ` $e.GetChildContent('is-nonempty') -match "false" ) { $Obj.AllowNull = $True } Else{ $Obj.AllowNull = $False } Switch ($objOutput) { {($Output -eq $true) -and ($_ -eq $true)} {write-output $obj} {($Output -eq $false) -and ($_ -eq $false)} {write-output $obj} } } } } } Function Get-NaType { Param( [NetApp.SDK.NaServer]$Server=$DefaultNaServer, [string]$Type ) process{ $NaElement = New-Object NetApp.Manage.NaElement("system-api-list-types") $results = $Server.InvokeElem($NaElement).GetChildByName("type-entries").getchildren() If ($type){ $results = $results | ?{$_.GetChildContent("name") -eq $type} } $results.GetChildByName("type-elements").getchildren() | Select @{ n='name' E={$_.GetChildContent("name")} }, @{ n='type' E={$_.GetChildContent("type")} }, @{ n='optional' E={$_.GetChildContent("is-optional")} } } } Function ConvertFrom-NaBool { <# .Synopsis Converts the string bool returned from the Na API into a proper bool type. .Description Converts the string bool returned from the Na API into a proper bool type. .Parameter bool string bool returned from the ONTAPI API. .Example convert the string false to $FALSE PS > ConvertFrom-NaBool "false" .Outputs system.bool .Link ConvertFrom-NaTime ConvertTo-NaTime #> [CmdletBinding(SupportsShouldProcess=$FALSE,SupportsTransactions=$False,ConfirmImpact="None",DefaultParameterSetName="")] param( [Parameter(Position=0,ValueFromPipeline=$True,HelpMessage="string bool returned from the Na API.")] [string[]] $bool ) process { switch ($bool) { "false" {return $FALSE} "true" {return $TRUE} default {return $null} } } } Function ConvertFrom-NaTime { <# .Synopsis Converts the time object returned by the na API into [DateTime] objects .Description Converts the time object returned by the na API into [DateTime] objects Filers record time in the format of seconds since Jan/1/1970. Some portions of the SDK will return GMT regaurdless of any reginalizaion settings. .Parameter Time Seconds since 1/1/1970 .Parameter UTC Specifies that the time needs to be converted from UTC/GMT. .Example convert 1230163200 from seconds since 1/1/1970 to [DateTime]. ConvertFrom-NaTime 1230163200 .Outputs system.DateTime .Link ConvertFrom-NaBool ConvertTo-NaTime #> [CmdletBinding(SupportsShouldProcess=$FALSE,SupportsTransactions=$False,ConfirmImpact="None",DefaultParameterSetName="")] param( [Parameter(Position=0,ValueFromPipeline=$True,HelpMessage="Seconds since 1/1/1970")] [int64] $Time, [Parameter()] [switch] $UTC ) process { if ($UTC) { return (New-Object Datetime -ArgumentList @(1970,1,1,0,0,0,[DateTimeKind]1)).AddSeconds($time).ToLocalTime() } else { return (New-Object Datetime -ArgumentList @(1970,1,1,0,0,0)).AddSeconds($time).ToLocalTime() } } } Function ConvertTo-NaTime { <# .Synopsis Converts a proper [DateTime] object to the time formate used by filers. .Description Converts a proper [DateTime] object to the time formate used by filers. Filers record time in the format of seconds since Jan/1/1970. Some portions of the SDK will return GMT regaurdless of any localization settings. In these instances you will need to specify the -UTC switch. .Parameter Time Datetime to be converted .Example #convert 12/25/2008 to the correct format for the filers. PS > ConvertTo-NaTime [DateTime]'12/25/2008' .Outputs system.string .Link ConvertFrom-NaBool ConvertFrom-NaTime #> [CmdletBinding(SupportsShouldProcess=$FALSE,SupportsTransactions=$False,ConfirmImpact="None",DefaultParameterSetName="")] param( [Parameter(Mandatory=$TRUE,Position=0,ValueFromPipeline=$True, HelpMessage="Datetime to be converted")] [DateTime] $Time ) process { return [Int64]([math]::ROUND((($Time.ToUniversalTime()).subtract((New-Object Datetime -ArgumentList @(1970,1,1,0,0,0)).ToLocalTime())).TotalSeconds)) } }