This tutorial will give an introduction to the OnCommand Insight PowerShell Cmdlets
Load the OCI Module
Import-Module OnCommand-InsightShow all available Cmdlets from the OCI Module
Get-Command -Module OnCommand-InsightShow the syntax of all Cmdlets from the OCI Module
Get-Command -Module OnCommand-Insight -SyntaxTo get detailed help including examples for a specific Cmdlet (e.g. for Connect-OciServer) run
Get-Help Connect-OciServer -DetailedFor data retrieval a connection to the OCI Server is required. The Connect-OciServer Cmdlet expects the hostname or IP and the credentials for authentication
$ServerName = 'ociserver.example.com'
$Credential = Get-Credential
Connect-OciServer -Name $ServerName -Credential $CredentialIf the login fails, it is often due to an untrusted certificate of the OCI Server. You can ignore the certificate check with the -insecure option
Additionally, you can now import the OCI Server certificate into the Trusted Root Certification Authorities. This allows connections to be trusted via PowerShell and Browsers such as Internet Explorer.
Import-OciServerCertificate -Name $ServerNameYou can also remove the certificate from the Trusted Root Certification Authorities with
Remove-OciServerCertificate -Name $ServerNameConnect-OciServer -Name $ServerName -Credential $Credential -InsecureBy default the connection to the OCI server is established through HTTPS. If that doesn't work, HTTP will be tried.
To force connections via HTTPS use the -HTTPS switch
Connect-OciServer -Name $ServerName -Credential $Credential -HTTPSTo force connections via HTTP use the -HTTP switch (HTTP is not available in OCI 7.2 and later)
Connect-OciServer -Name $ServerName -Credential $Credential -HTTPAs the timezone of the OCI Server is not available via the REST API, it needs to be manually set so that all timestamps are displayed with the correct timezone. By default the timezone will be set to the local timezone of the PowerShell environment.
A list of all available timezones can be shown with
[System.TimeZoneInfo]::GetSystemTimeZones()You can set a different than the local timezone when connecting to the OCI server with e.g.
Connect-OciServer -Name $ServerName -Timezone "Pacific Standard Time"The currently configured timezone of the OCI Server can be checked with
$CurrentOciServer.TimezoneTo manually set a different timezone (e.g. CEST or PST), the following command can be used
$CurrentOciServer.Timezone = [System.TimeZoneInfo]::FindSystemTimeZoneById("Central Europe Standard Time")
$CurrentOciServer.Timezone = [System.TimeZoneInfo]::FindSystemTimeZoneById("Pacific Standard Time")In this simple workflow the available storage systems will be retrieved, a NetApp FAS system will be choosen and then all internal volumes for this system will be retrieved.
$Storages = Get-OciStorages
$NetAppStorages = $Storages | ? { $_.vendor -eq "NetApp" -and $_.family -match "FAS" } | Select-Object -First 1
$NetAppStorages | Get-OciInternalVolumesByStorageAs the OCI Cmdlets support pipelining, the above statements can be combined into one statement:
Get-OciStorages | ? { $_.vendor -eq "NetApp" -and $_.family -match "FAS" } | Select-Object -First 1 | Get-OciInternalVolumesByStorageTo retrieve all devices of all datasources you can use the following command. For large environments, especially with a large number of ESX Hosts, this command can take some time:
Get-OciDatasources -DevicesThe following command will get all Volumes with all Performance Data. For everything else then small test environments this can result in huge amounts of data. Make sure to either only get the volumes for one storage system or restrict the timeframe for which you want to retrieve performance data with -fromTime and -toTime:
$VolumesWithPerformance = Get-OciStorages | Get-OciVolumesByStorage -Performance -fromTime (Get-Date).addDays(-1)To extract just the Minimum, Maximum and Average IOPS and pretty print the data use:
$VolumesWithPerformance | % { [PSCustomObject]@{Name=$_.Name;"Min total IOPS"=$_.performance.iops.total.min;"Max total IOPS"=$_.performance.iops.total.max; "Avg total IOPS"=$_.performance.iops.total.avg} } | ft -WrapThe OCI API allows to get related objects. E.g. for the internal volume it is possible to get related storage, performance, dataStores, computeResources, storagePool, volumes, storageNodes, applications, annotations, replicaSources, performancehistory. The related objects can be retrieved by specifying paramter switches. These can be shown with get-help:
get-help Get-OciInternalVolume -DetailedTo retrieve all related objects for e.g. internal volumes use
Get-OciStorages | Get-OciInternalVolumesByStorage | Select -first 1 | Get-OciInternalVolume -storage -performance -dataStores -computeResources -storagePool -volumes -storageNodes -applications -annotations -replicaSources -performancehistory -datasources -qtreesApplications can be of type DATE, TEXT, FIXED_ENUM, FLEXIBLE_ENUM, BOOLEAN or NUMBER. TEXT is the most flexible, but FLEXIBLE_ENUM may also be a good choice if the number of different values is low. FLEXIBLE_ENUM will automatically extend the list of values if a new value is added. FIXED_ENUM will only allow the predefined values and will give an error if an undefined value is added.
Add an application of type FLEXIBLE_ENUM
Add-OciAnnotation -Name "Enum test" -Type FLEXIBLE_ENUM -Description "Enum test description" -enumValues @{name="Item name";label="Item label"}Get all annotations
Get-OciAnnotationsGet the previously added annotation
$Annotation = Get-OciAnnotations | ? { $_.Name -eq "Enum test" }The Update-OciAnnotation Cmdlet always overwrites all parameters of the annotation, thus it is recommended to get the existing Annotation, modify it and then pass the modified Annotation via the Pipeline to Update-OciAnnotation.
Here is an example to update the enum values of a FIXED_ENUM Annotation:
$newEnumValues = @(@{name="two";label="two"},@{name="three";label="three"})
foreach ($newEnumValue in $newEnumValues) {
# remove enum with same name as newEnumValue to prevent duplicates
$Annotation.enumValues = $Annotation.enumValues | Where-Object { $_.Name -ne $newEnumValue.Name }
$Annotation.enumValues = @($Annotation.enumValues) + [PSCustomObject]$newEnumValue
}
$Annotation = $Annotation | Update-OciAnnotation -VerboseRetrieve a volume
$Volume = Get-OciStorages | Get-OciVolumesByStorage | select -first 1Show all annotations of the volume
$Volume | Get-OciAnnotationsByVolumeAdd the previously defined annotation to the volume with a new value
$Annotation | Update-OciAnnotationValues -objectType "Volume" -rawValue "New item" -targets $Volume.idCheck the annotation values of the annotation
$Annotation | Get-OciAnnotationValuesGet the annotation and check that it contains the new value "New item"
$Annotation | Get-OciAnnotation | Select -expandProperty enumValuesOCI does not support deleting all annotation values out of the box, but the PowerShell Cmdlets do by first getting all values of an annotation and then removing them. Just run
$Annotation | Remove-OciAnnotationValuesCheck that the values have been deleted
$Annotation | Get-OciAnnotationValuesYou can create a Business Entity with
$BusinessUnity = Add-OciBusinessEntity -Tenant "tenant" -LineOfBusiness "lof" -BusinessUnit "bu" -Project "project"You can get all Business Entities with
Get-OciBusinessEntitiesYou can remove all Business Entities with
Get-OciBusinessEntities | Remove-OciBusinessEntitiesYou can create a Application with
$Application = Add-OciApplication -name "application" -priority Critical -businessEntity $BusinessEntity.id -ignoreShareViolationsYou can update an application with
$Application | Update-OciApplication -priority LowRemove all applications
Get-OciApplications | Remove-OciApplicationGet-OciHealthAn easy way to show tabular data and to filter columns is included in PowerShell with the Grid-View.
To show output in the Grid-View use
Get-OciStorages | Out-Gridview -Title 'Storages'Retrieve OCI data (e.g. Storage Arrays)
$Storages = Get-OciStoragesSpecify filename, encording and delimiter for CSV file, then export to CSV
$FileName = 'C:\tmp\test.csv'
$Encoding = 'UTF8'
$Delimiter = ';'
$Storages | Export-Csv -NoTypeInformation -Path $FileName -Encoding $Encoding -Delimiter $DelimiterInstall PSExcel from https://github.com/RamblingCookieMonster/PSExcel and load PSExcel Module
Import-Module PSExcel
Retrieve OCI data (e.g. Storage Arrays)
$Storages = Get-OciStoragesSpecify filename and worksheet name for the Excel file. Then export to Excel
$FileName = "$HOME\Documents\Ocitest.xlsx"
$WorksheetName = 'Storage Arrays'
$Storages | Export-XLSX -Path $FileName -WorksheetName $WorksheetName -Table -TableStyle Light1 -AutoFitYou can easily add another worksheet to an existing Excel file with
$WorksheetName = 'Additional worksheet'
$Storages | Export-XLSX -Path $FileName -WorksheetName $WorksheetName -Table -TableStyle Light1 -AutoFitTo create a single Excel file with many OCI objects, run the following commands
$FileName = "$HOME\Documents\OciOverview.xlsx"
Get-OciAcquisitionUnits | Export-XLSX -Path $FileName -WorksheetName 'Acquisition Units' -Table -TableStyle Light1 -AutoFit
Get-OciAnnotations | Export-XLSX -Path $FileName -WorksheetName 'Annotations' -Table -TableStyle Light1 -AutoFit
Get-OciApplications | Export-XLSX -Path $FileName -WorksheetName 'Applications' -Table -TableStyle Light1 -AutoFit
Get-OciDatasources | Export-XLSX -Path $FileName -WorksheetName 'Datasources' -Table -TableStyle Light1 -AutoFit
Get-OciDatastores | Export-XLSX -Path $FileName -WorksheetName 'Datastores' -Table -TableStyle Light1 -AutoFit
Get-OciStorages | Get-OciDisksByStorage | Export-XLSX -Path $FileName -WorksheetName 'Disks' -Table -TableStyle Light1 -AutoFit
Get-OciFabrics | Export-XLSX -Path $FileName -WorksheetName 'Fabrics' -Table -TableStyle Light1 -AutoFit
Get-OciHosts | Get-OciFileSystemsByHost | Export-XLSX -Path $FileName -WorksheetName 'Filesystems' -Table -TableStyle Light1 -AutoFit
Get-OciHealth | Export-XLSX -Path $FileName -WorksheetName 'Health' -Table -TableStyle Light1 -AutoFit
Get-OciHosts | Export-XLSX -Path $FileName -WorksheetName 'Hosts' -Table -TableStyle Light1 -AutoFit
Get-OciStorages | Get-OciInternalVolumesByStorage | Export-XLSX -Path $FileName -WorksheetName 'Internal Volumes' -Table -TableStyle Light1 -AutoFit
Get-OciLicenses | Export-XLSX -Path $FileName -WorksheetName 'Licenses' -Table -TableStyle Light1 -AutoFit
Get-OciPatches | Export-XLSX -Path $FileName -WorksheetName 'Patches' -Table -TableStyle Light1 -AutoFit
Get-OciStorages | Get-OciStorageNodesByStorage | Export-XLSX -Path $FileName -WorksheetName 'Storage Nodes' -Table -TableStyle Light1 -AutoFit
Get-OciStorages | Get-OciStoragePoolsByStorage | Export-XLSX -Path $FileName -WorksheetName 'Storage Pools' -Table -TableStyle Light1 -AutoFit
Get-OciStorages | Export-XLSX -Path $FileName -WorksheetName 'Storages' -Table -TableStyle Light1 -AutoFit
Get-OciSwitches | Export-XLSX -Path $FileName -WorksheetName 'Switches' -Table -TableStyle Light1 -AutoFit
Get-OciUsers | Export-XLSX -Path $FileName -WorksheetName 'Users' -Table -TableStyle Light1 -AutoFit
Get-OciVirtualMachines | Export-XLSX -Path $FileName -WorksheetName 'Virtual Machines' -Table -TableStyle Light1 -AutoFit
Get-OciVirtualMachines | Get-OciVmdksByVirtualMachine | Export-XLSX -Path $FileName -WorksheetName 'VMDKs' -Table -TableStyle Light1 -AutoFit
Get-OciStorages | Get-OciVolumesByStorage | Export-XLSX -Path $FileName -WorksheetName 'Volumes' -Table -TableStyle Light1 -AutoFit$Datasources = Get-OciDatasources -devices
$DuplicateDevices = $Datasources.devices.Name | Group-Object | ? { $_.Count -gt 1 } | Select -ExpandProperty Name
foreach ($Device in $DuplicateDevices) {
"$Device," + (($Datasources | ? { $_.Devices.name -match $Device } | select -ExpandProperty Name) -join ',')
}First get a list of all supported datasource types
Get-OciDatasourceTypesSelect the datasource type you want to configure:
$type = Get-OciDatasourceTypes | ? { $_.description -match "CMode" }Select the acquisition unit to use for the datasource:
$acquisitionUnit = Get-OciAcquisitionUnits | Select -first 1Now create a new datasource from the type to work with locally (this does not create anything on the server yet!):
$Datasource = New-OciDatasource -name "test" -acquisitionUnit $acquisitionUnit -type $typeRegardless of the datasource type, all datasources will have a foundation package. Other packages like storageperformance, cloud, hostvirtualization are datasource type specific. Check the available packages and their attributes with
$Datasource.config.packages
$Datasource.config.foundation.attributes
$Datasource.config.storageperformance.attributesThe attributes are filled with the default values from the type definition. You may now change some of the attributes
$Datasource.config.foundation.attributes.forceTLS = $true
$Datasource.config.foundation.attributes.ip = "192.168.1.100"To set username and password, it is recommended to use Get-Credential:
$Credential = Get-Credential
$Datasource.config.foundation.attributes.user = $Credential.UserName
$Datasource.config.foundation.attributes.password = $Credential.GetNetworkCredential().passwordMost additional packages like storageperformance are disabled by default and need to be enabled
$Datasource.config.storageperformance.attributes.enabled = $trueNow the datasource can be added to the OCI server
$Datasource = $Datasource | Add-OciDatasourceCheck that the status of the datasource changes to success which indicates successfull collection of data
$Datasource | Get-OciDatasourceTo remove the datasource, use
$Datasource | Remove-OciDatasourceGet all datasources including its configuration
Get-OciDatasources -configGet a single datasource including its configuration
Get-OciDatasource -id 1 -configThe configuration contains packages (e.g. foundation, performance, cloud) and each package has several attributes which can be modified.
Here's an example to change the password of a single datasource:
$Datasource = Get-OciDatasources | Select -first 1 | Get-OciDatasource -config
# modify password attribute
$Datasource.config.foundation.attributes.password = "test"
# update datasource
$Datasource | Update-OciDatasourceHere's an example to change the password of all datasources:
$Datasources = Get-OciDatasources -config
# modify password attribute
$Datasources | % { $_.config.foundation.attributes.password = "test" }
# update datasources
$Datasources | Update-OciDatasourceHere's a full interactive example for datasource password management including verification that the change was successfull.
Import-Module OnCommand-Insight
$ServerName = Read-Host -Prompt "Please insert OnCommand Insight Server full qualified hostname"
$Credential = Get-Credential -Message "Please enter credentials to access OnCommand Insight server"
Connect-OciServer -Name $ServerName -Credential $Credential -HTTPS -Insecure
$Datasources = Get-OciDatasources -config
$DatasourceCredential = Get-Credential -Message "Please enter new credentials to be used by datasources"
foreach ($Datasource in $Datasources) {
$Datasource.config.foundation.attributes.user = $DatasourceCredential.UserName
$Datasource.config.foundation.attributes.password = $DatasourceCredential.GetNetworkCredential().password
$Datasource = $Datasource | Update-OciDatasource
}
foreach ($Datasource in $Datasources) {
$Tests = $Datasource | Test-OciDatasource
foreach ($Test in $Tests) {
if ($Test.result -eq "PASSED") {
$Test.message = $Test.message -replace "Configuration:","Datasource $($Datasource.Name):"
Write-Host $Test.message -ForegroundColor Green
}
else {
$Test.message = $Test.message -replace "Configuration:","Datasource $($Datasource.Name):"
Write-Host $Test.message -ForegroundColor Red
}
}
}The LDAP Configuration can be retrieved via
Get-OciLdapConfigurationHere's a full example for LDAP configuration changes
Import-Module OnCommand-Insight
$LdapServer = Read-Host -Prompt "Please insert LDAP URI (e.g. ldaps://dc1.example.com:636,ldaps://dc2.example.com)"
$LdapDomain = Read-Host -Prompt "Please insert LDAP Domain (e.g. DC=example,DC=com)"
$LdapAdminGroups = Read-Host -Prompt "Please insert LDAP group for Admin role"
$LdapCredential = Get-Credential -Message "Please provide credential for accessing LDAP server"
$Test = Test-OciLdapConfiguration -LdapServer $LdapServer -UserName $LdapCredential.UserName -Password $LdapCredential.GetNetworkCredential().password -Verbose
if ($Test.statusCode -eq "SUCCESS") {
Write-Host "Connection to LDAP Server $LdapServer with user $($LdapCredential.UserName) succeeded" -ForegroundColor green
} else {
Write-Host "Connection to LDAP Server $LdapServer with user $($LdapCredential.UserName) failed" -ForegroundColor red
}
$LdapConfiguration = Get-OciLdapConfiguration
$LdapConfiguration.isEnabled = $true
$LdapConfiguration.directoryLookup.server = $LdapServer
$LdapConfiguration.directoryLookup.userName = $LdapCredential.UserName
$LdapConfiguration.directoryLookup.password = $LdapCredential.GetNetworkCredential().Password
$LdapConfiguration.directoryLookup.domain = $LdapDomain
$LdapConfiguration.groups.admins = $LdapAdminGroups
$LdapConfiguration.attributes.userPrincipalName = "sAMAccountName"
$LdapConfiguration | Update-OciLdapConfigurationAll available Backups on the OCI Server can be retrieved with
Get-OciBackupsA backup can be created with and stored under C:\tmp
$Path = "C:\tmp"
Get-OciBackup -Path $PathA backup can be restored with
$BackupLocation = "C:\tmp\Backup_Lab_NetApp_Munich_V7-2-0_B773_D20160417_2300_4959387166860292236.zip
Restore-OciBackup -FilePath $BackupLocationThe latest Backup available on the OCI Server can be restored with
Get-OciBackups | Sort -Property Date -Descending | select -first 1 | Restore-OciBackupYou can add new OCI Patches (and service packs) via the following commands (replace path to the patchfile you want to add):
$patchFile = "$HOME\Downloads\7.2_SP5_Patches\7.2_SP5_Patches\netapp_7mode\7.2_ici-4588_netap_api.patch"
Add-OciPatch -patchFile $patchFileA new patch will be evaluated by OCI and if all datasources are either working as before, or improve from FAILED to SUCCESS, OCI will give a recommendation for approval of the patch
Get-OciPatchesYou can get individual patches with the conclusion OCI reached for each datasource with
Get-OciPatches | Get-OciPatch -datasourceConclusionIf the patch caused new issues, then a rollback may be neccessary. This can be done with
$PatchesToBeRolledBack = Get-OciPatches | where { $_.Recommendation -eq "Rollback" }
$PatchesToBeRolledBack | Rollback-OciPatchIf the patch was successfull, it can be approved with
$PatchesToBeApproved = Get-OciPatches | where { $_.Recommendation -eq "Approve" }You can add a comment to a patch with the following command:
Get-OciPatches | Update-OciPatchNote -value "test"If you encounter issues with timeouts, this may be due to slow OCI Servers or very large environments. Try increasing the Timout from the default of 600 seconds (10 minutes) when connecting to the OCI Server
$ServerName = 'localhost'
$Timeout = 1200
Connect-OciServer -Name $ServerName -Timeout $TimeoutAlternatively you can configure the timeout direcly using the $CurrentOciServer variable
$CurrentOciServer.Timeout = 1200