This tutorial will give an introduction to the OnCommand Insight PowerShell Cmdlets
Load the OCI Module
Import-Module OnCommand-Insight
Show all available Cmdlets from the OCI Module
Get-Command -Module OnCommand-Insight
Show the syntax of all Cmdlets from the OCI Module
Get-Command -Module OnCommand-Insight -Syntax
To get detailed help including examples for a specific Cmdlet (e.g. for Connect-OciServer) run
Get-Help Connect-OciServer -Detailed
For 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 $Credential
If 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 $ServerName
You can also remove the certificate from the Trusted Root Certification Authorities with
Remove-OciServerCertificate -Name $ServerName
Connect-OciServer -Name $ServerName -Credential $Credential -Insecure
By 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 -HTTPS
To force connections via HTTP use the -HTTP
switch (HTTP is not available in OCI 7.2 and later)
Connect-OciServer -Name $ServerName -Credential $Credential -HTTP
As 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.Timezone
To 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-OciInternalVolumesByStorage
As 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-OciInternalVolumesByStorage
To 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 -Devices
The 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 -Wrap
The 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 -Detailed
To 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 -qtrees
Applications 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-OciAnnotations
Get 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 -Verbose
Retrieve a volume
$Volume = Get-OciStorages | Get-OciVolumesByStorage | select -first 1
Show all annotations of the volume
$Volume | Get-OciAnnotationsByVolume
Add the previously defined annotation to the volume with a new value
$Annotation | Update-OciAnnotationValues -objectType "Volume" -rawValue "New item" -targets $Volume.id
Check the annotation values of the annotation
$Annotation | Get-OciAnnotationValues
Get the annotation and check that it contains the new value "New item"
$Annotation | Get-OciAnnotation | Select -expandProperty enumValues
OCI 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-OciAnnotationValues
Check that the values have been deleted
$Annotation | Get-OciAnnotationValues
You 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-OciBusinessEntities
You can remove all Business Entities with
Get-OciBusinessEntities | Remove-OciBusinessEntities
You can create a Application with
$Application = Add-OciApplication -name "application" -priority Critical -businessEntity $BusinessEntity.id -ignoreShareViolations
You can update an application with
$Application | Update-OciApplication -priority Low
Remove all applications
Get-OciApplications | Remove-OciApplication
Get-OciHealth
An 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-OciStorages
Specify 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 $Delimiter
Install PSExcel from https://github.com/RamblingCookieMonster/PSExcel and load PSExcel Module
Import-Module PSExcel
Retrieve OCI data (e.g. Storage Arrays)
$Storages = Get-OciStorages
Specify 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 -AutoFit
You can easily add another worksheet to an existing Excel file with
$WorksheetName = 'Additional worksheet'
$Storages | Export-XLSX -Path $FileName -WorksheetName $WorksheetName -Table -TableStyle Light1 -AutoFit
To 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-OciDatasourceTypes
Select 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 1
Now 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 $type
Regardless 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.attributes
The 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().password
Most additional packages like storageperformance are disabled by default and need to be enabled
$Datasource.config.storageperformance.attributes.enabled = $true
Now the datasource can be added to the OCI server
$Datasource = $Datasource | Add-OciDatasource
Check that the status of the datasource changes to success which indicates successfull collection of data
$Datasource | Get-OciDatasource
To remove the datasource, use
$Datasource | Remove-OciDatasource
Get all datasources including its configuration
Get-OciDatasources -config
Get a single datasource including its configuration
Get-OciDatasource -id 1 -config
The 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-OciDatasource
Here'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-OciDatasource
Here'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-OciLdapConfiguration
Here'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-OciLdapConfiguration
All available Backups on the OCI Server can be retrieved with
Get-OciBackups
A backup can be created with and stored under C:\tmp
$Path = "C:\tmp"
Get-OciBackup -Path $Path
A backup can be restored with
$BackupLocation = "C:\tmp\Backup_Lab_NetApp_Munich_V7-2-0_B773_D20160417_2300_4959387166860292236.zip
Restore-OciBackup -FilePath $BackupLocation
The latest Backup available on the OCI Server can be restored with
Get-OciBackups | Sort -Property Date -Descending | select -first 1 | Restore-OciBackup
You 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 $patchFile
A 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-OciPatches
You can get individual patches with the conclusion OCI reached for each datasource with
Get-OciPatches | Get-OciPatch -datasourceConclusion
If 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-OciPatch
If 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 $Timeout
Alternatively you can configure the timeout direcly using the $CurrentOciServer variable
$CurrentOciServer.Timeout = 1200