OnCommand-Insight.psm1

# including Credential Manager cmdlets
<#
.Synopsis
  Provides access to Windows CredMan basic functionality for client scripts
 
****************** IMPORTANT ******************
*
* If you use this script from the PS console, you
* should ALWAYS pass the Target, User and Password
* parameters using single quotes:
*
* .\CredMan.ps1 -AddCred -Target 'http://server' -User 'JoeSchmuckatelli' -Pass 'P@55w0rd!'
*
* to prevent PS misinterpreting special characters
* you might use as PS reserved characters
*
****************** IMPORTANT ******************
 
.Description
  Provides the following API when dot-sourced
  Remove-WindowsCredential
  Get-WindowsCredentials
  Get-WindowsCredential
  Add-WindowsCredential
 
.INPUTS
  See function-level notes
 
.OUTPUTS
  Cmd-line usage: console output relative to success or failure state
  Dot-sourced usage:
  ** Successful Action **
  * Remove-WindowsCredential : Int = 0
  * Get-WindowsCredentials : PsUtils.CredMan+Credential[]
  * Get-WindowsCredential : PsUtils.CredMan+Credential
  * Add-WindowsCredential : Int = 0
  ** Failure **
  * All API : Management.Automation.ErrorRecord
 
.NOTES
 
  Author: Jim Harrison (jim@isatools.org)
  Date : 2012/05/20
  Vers : 1.5
   
  Updates:
  2012/10/13
          - Fixed a bug where the script would only read, write or delete GENERIC
          credentials types.
                - Added #region blocks to clarify internal functionality
                - Added 'CredType' param to specify what sort of credential is to be read,
                created or deleted (not used for -ShoCred or Enum-Creds)
                - Added 'CredPersist' param to specify how the credential is to be stored;
                only used in Write-Cred
                - Added 'All' param for -ShoCreds to differentiate between creds summary
                list and detailed creds dump
                - Added CRED_FLAGS enum to make the credential struct flags values clearer
                - Improved parameter validation
                - Expanded internal help (used with Get-Help cmdlet)
                - Cmd-line functions better illustrate how to interpret the results when
                dot-sourcing the script
 
.LINK
    http://msdn.microsoft.com/en-us/library/windows/desktop/aa374788(v=vs.85).aspx
    http://stackoverflow.com/questions/7162604/get-cached-credentials-in-powershell-from-windows-7-credential-manager
    http://msdn.microsoft.com/en-us/library/windows/desktop/aa374788(v=vs.85).aspx
    http://blogs.msdn.com/b/peerchan/archive/2005/11/01/487834.aspx
#>


#region Pinvoke
#region Inline C#
[String] $PsCredmanUtils = @"
using System;
using System.Runtime.InteropServices;
 
namespace PsUtils
{
    public class CredMan
    {
        #region Imports
        // DllImport derives from System.Runtime.InteropServices
        [DllImport("Advapi32.dll", SetLastError = true, EntryPoint = "CredDeleteW", CharSet = CharSet.Unicode)]
        private static extern bool CredDeleteW([In] string target, [In] CRED_TYPE type, [In] int reservedFlag);
 
        [DllImport("Advapi32.dll", SetLastError = true, EntryPoint = "CredEnumerateW", CharSet = CharSet.Unicode)]
        private static extern bool CredEnumerateW([In] string Filter, [In] int Flags, out int Count, out IntPtr CredentialPtr);
 
        [DllImport("Advapi32.dll", SetLastError = true, EntryPoint = "CredFree")]
        private static extern void CredFree([In] IntPtr cred);
 
        [DllImport("Advapi32.dll", SetLastError = true, EntryPoint = "CredReadW", CharSet = CharSet.Unicode)]
        private static extern bool CredReadW([In] string target, [In] CRED_TYPE type, [In] int reservedFlag, out IntPtr CredentialPtr);
 
        [DllImport("Advapi32.dll", SetLastError = true, EntryPoint = "CredWriteW", CharSet = CharSet.Unicode)]
        private static extern bool CredWriteW([In] ref Credential userCredential, [In] UInt32 flags);
        #endregion
 
        #region Fields
        public enum CRED_FLAGS : uint
        {
            NONE = 0x0,
            PROMPT_NOW = 0x2,
            USERNAME_TARGET = 0x4
        }
 
        public enum CRED_ERRORS : uint
        {
            ERROR_SUCCESS = 0x0,
            ERROR_INVALID_PARAMETER = 0x80070057,
            ERROR_INVALID_FLAGS = 0x800703EC,
            ERROR_NOT_FOUND = 0x80070490,
            ERROR_NO_SUCH_LOGON_SESSION = 0x80070520,
            ERROR_BAD_USERNAME = 0x8007089A
        }
 
        public enum CRED_PERSIST : uint
        {
            SESSION = 1,
            LOCAL_MACHINE = 2,
            ENTERPRISE = 3
        }
 
        public enum CRED_TYPE : uint
        {
            GENERIC = 1,
            DOMAIN_PASSWORD = 2,
            DOMAIN_CERTIFICATE = 3,
            DOMAIN_VISIBLE_PASSWORD = 4,
            GENERIC_CERTIFICATE = 5,
            DOMAIN_EXTENDED = 6,
            MAXIMUM = 7, // Maximum supported cred type
            MAXIMUM_EX = (MAXIMUM + 1000), // Allow new applications to run on old OSes
        }
 
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct Credential
        {
            public CRED_FLAGS Flags;
            public CRED_TYPE Type;
            public string TargetName;
            public string Comment;
            public DateTime LastWritten;
            public UInt32 CredentialBlobSize;
            public string CredentialBlob;
            public CRED_PERSIST Persist;
            public UInt32 AttributeCount;
            public IntPtr Attributes;
            public string TargetAlias;
            public string UserName;
        }
 
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        private struct NativeCredential
        {
            public CRED_FLAGS Flags;
            public CRED_TYPE Type;
            public IntPtr TargetName;
            public IntPtr Comment;
            public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten;
            public UInt32 CredentialBlobSize;
            public IntPtr CredentialBlob;
            public UInt32 Persist;
            public UInt32 AttributeCount;
            public IntPtr Attributes;
            public IntPtr TargetAlias;
            public IntPtr UserName;
        }
        #endregion
 
        #region Child Class
        private class CriticalCredentialHandle : Microsoft.Win32.SafeHandles.CriticalHandleZeroOrMinusOneIsInvalid
        {
            public CriticalCredentialHandle(IntPtr preexistingHandle)
            {
                SetHandle(preexistingHandle);
            }
 
            private Credential XlateNativeCred(IntPtr pCred)
            {
                NativeCredential ncred = (NativeCredential)Marshal.PtrToStructure(pCred, typeof(NativeCredential));
                Credential cred = new Credential();
                cred.Type = ncred.Type;
                cred.Flags = ncred.Flags;
                cred.Persist = (CRED_PERSIST)ncred.Persist;
 
                long LastWritten = ncred.LastWritten.dwHighDateTime;
                LastWritten = (LastWritten << 32) + ncred.LastWritten.dwLowDateTime;
                cred.LastWritten = DateTime.FromFileTime(LastWritten);
 
                cred.UserName = Marshal.PtrToStringUni(ncred.UserName);
                cred.TargetName = Marshal.PtrToStringUni(ncred.TargetName);
                cred.TargetAlias = Marshal.PtrToStringUni(ncred.TargetAlias);
                cred.Comment = Marshal.PtrToStringUni(ncred.Comment);
                cred.CredentialBlobSize = ncred.CredentialBlobSize;
                if (0 < ncred.CredentialBlobSize)
                {
                    cred.CredentialBlob = Marshal.PtrToStringUni(ncred.CredentialBlob, (int)ncred.CredentialBlobSize / 2);
                }
                return cred;
            }
 
            public Credential GetCredential()
            {
                if (IsInvalid)
                {
                    throw new InvalidOperationException("Invalid CriticalHandle!");
                }
                Credential cred = XlateNativeCred(handle);
                return cred;
            }
 
            public Credential[] GetCredentials(int count)
            {
                if (IsInvalid)
                {
                    throw new InvalidOperationException("Invalid CriticalHandle!");
                }
                Credential[] Credentials = new Credential[count];
                IntPtr pTemp = IntPtr.Zero;
                for (int inx = 0; inx < count; inx++)
                {
                    pTemp = Marshal.ReadIntPtr(handle, inx * IntPtr.Size);
                    Credential cred = XlateNativeCred(pTemp);
                    Credentials[inx] = cred;
                }
                return Credentials;
            }
 
            override protected bool ReleaseHandle()
            {
                if (IsInvalid)
                {
                    return false;
                }
                CredFree(handle);
                SetHandleAsInvalid();
                return true;
            }
        }
        #endregion
 
        #region Custom API
        public static int CredDelete(string target, CRED_TYPE type)
        {
            if (!CredDeleteW(target, type, 0))
            {
                return Marshal.GetHRForLastWin32Error();
            }
            return 0;
        }
 
        public static int CredEnum(string Filter, out Credential[] Credentials)
        {
            int count = 0;
            int Flags = 0x0;
            if (string.IsNullOrEmpty(Filter) ||
                "*" == Filter)
            {
                Filter = null;
                if (6 <= Environment.OSVersion.Version.Major)
                {
                    Flags = 0x1; //CRED_ENUMERATE_ALL_CREDENTIALS; only valid is OS >= Vista
                }
            }
            IntPtr pCredentials = IntPtr.Zero;
            if (!CredEnumerateW(Filter, Flags, out count, out pCredentials))
            {
                Credentials = null;
                return Marshal.GetHRForLastWin32Error();
            }
            CriticalCredentialHandle CredHandle = new CriticalCredentialHandle(pCredentials);
            Credentials = CredHandle.GetCredentials(count);
            return 0;
        }
 
        public static int CredRead(string target, CRED_TYPE type, out Credential Credential)
        {
            IntPtr pCredential = IntPtr.Zero;
            Credential = new Credential();
            if (!CredReadW(target, type, 0, out pCredential))
            {
                return Marshal.GetHRForLastWin32Error();
            }
            CriticalCredentialHandle CredHandle = new CriticalCredentialHandle(pCredential);
            Credential = CredHandle.GetCredential();
            return 0;
        }
 
        public static int CredWrite(Credential userCredential)
        {
            if (!CredWriteW(ref userCredential, 0))
            {
                return Marshal.GetHRForLastWin32Error();
            }
            return 0;
        }
 
        #endregion
 
        private static int AddCred()
        {
            Credential Cred = new Credential();
            string Password = "Password";
            Cred.Flags = 0;
            Cred.Type = CRED_TYPE.GENERIC;
            Cred.TargetName = "Target";
            Cred.UserName = "UserName";
            Cred.AttributeCount = 0;
            Cred.Persist = CRED_PERSIST.ENTERPRISE;
            Cred.CredentialBlobSize = (uint)Password.Length;
            Cred.CredentialBlob = Password;
            Cred.Comment = "Comment";
            return CredWrite(Cred);
        }
 
        private static bool CheckError(string TestName, CRED_ERRORS Rtn)
        {
            switch(Rtn)
            {
                case CRED_ERRORS.ERROR_SUCCESS:
                    Console.WriteLine(string.Format("'{0}' worked", TestName));
                    return true;
                case CRED_ERRORS.ERROR_INVALID_FLAGS:
                case CRED_ERRORS.ERROR_INVALID_PARAMETER:
                case CRED_ERRORS.ERROR_NO_SUCH_LOGON_SESSION:
                case CRED_ERRORS.ERROR_NOT_FOUND:
                case CRED_ERRORS.ERROR_BAD_USERNAME:
                    Console.WriteLine(string.Format("'{0}' failed; {1}.", TestName, Rtn));
                    break;
                default:
                    Console.WriteLine(string.Format("'{0}' failed; 0x{1}.", TestName, Rtn.ToString("X")));
                    break;
            }
            return false;
        }
 
        /*
         * Note: the Main() function is primarily for debugging and testing in a Visual
         * Studio session. Although it will work from PowerShell, it's not very useful.
         */
        public static void Main()
        {
            Credential[] Creds = null;
            Credential Cred = new Credential();
            int Rtn = 0;
 
            Console.WriteLine("Testing CredWrite()");
            Rtn = AddCred();
            if (!CheckError("CredWrite", (CRED_ERRORS)Rtn))
            {
                return;
            }
            Console.WriteLine("Testing CredEnum()");
            Rtn = CredEnum(null, out Creds);
            if (!CheckError("CredEnum", (CRED_ERRORS)Rtn))
            {
                return;
            }
            Console.WriteLine("Testing CredRead()");
            Rtn = CredRead("Target", CRED_TYPE.GENERIC, out Cred);
            if (!CheckError("CredRead", (CRED_ERRORS)Rtn))
            {
                return;
            }
            Console.WriteLine("Testing CredDelete()");
            Rtn = CredDelete("Target", CRED_TYPE.GENERIC);
            if (!CheckError("CredDelete", (CRED_ERRORS)Rtn))
            {
                return;
            }
            Console.WriteLine("Testing CredRead() again");
            Rtn = CredRead("Target", CRED_TYPE.GENERIC, out Cred);
            if (!CheckError("CredRead", (CRED_ERRORS)Rtn))
            {
                Console.WriteLine("if the error is 'ERROR_NOT_FOUND', this result is OK.");
            }
        }
    }
}
"@

#endregion

$PsCredMan = $null
try
{
    $PsCredMan = [PsUtils.CredMan]
}
catch
{
    #only remove the error we generate
    if ($Error) {
        $Error.RemoveAt($Error.Count-1)
    }
}
if($null -eq $PsCredMan)
{
    Add-Type $PsCredmanUtils
}
#endregion

#region Internal Tools
[HashTable] $ErrorCategory = @{0x80070057 = "InvalidArgument";
                               0x800703EC = "InvalidData";
                               0x80070490 = "ObjectNotFound";
                               0x80070520 = "SecurityError";
                               0x8007089A = "SecurityError"}

function Get-CredType
{
    Param
    (
        [Parameter(Mandatory=$true)][ValidateSet("GENERIC",
                                                  "DOMAIN_PASSWORD",
                                                  "DOMAIN_CERTIFICATE",
                                                  "DOMAIN_VISIBLE_PASSWORD",
                                                  "GENERIC_CERTIFICATE",
                                                  "DOMAIN_EXTENDED",
                                                  "MAXIMUM",
                                                  "MAXIMUM_EX")][String] $CredType
    )
    
    switch($CredType)
    {
        "GENERIC" {return [PsUtils.CredMan+CRED_TYPE]::GENERIC}
        "DOMAIN_PASSWORD" {return [PsUtils.CredMan+CRED_TYPE]::DOMAIN_PASSWORD}
        "DOMAIN_CERTIFICATE" {return [PsUtils.CredMan+CRED_TYPE]::DOMAIN_CERTIFICATE}
        "DOMAIN_VISIBLE_PASSWORD" {return [PsUtils.CredMan+CRED_TYPE]::DOMAIN_VISIBLE_PASSWORD}
        "GENERIC_CERTIFICATE" {return [PsUtils.CredMan+CRED_TYPE]::GENERIC_CERTIFICATE}
        "DOMAIN_EXTENDED" {return [PsUtils.CredMan+CRED_TYPE]::DOMAIN_EXTENDED}
        "MAXIMUM" {return [PsUtils.CredMan+CRED_TYPE]::MAXIMUM}
        "MAXIMUM_EX" {return [PsUtils.CredMan+CRED_TYPE]::MAXIMUM_EX}
    }
}

function Get-CredPersist
{
    Param
    (
        [Parameter(Mandatory=$true)][ValidateSet("SESSION",
                                                  "LOCAL_MACHINE",
                                                  "ENTERPRISE")][String] $CredPersist
    )
    
    switch($CredPersist)
    {
        "SESSION" {return [PsUtils.CredMan+CRED_PERSIST]::SESSION}
        "LOCAL_MACHINE" {return [PsUtils.CredMan+CRED_PERSIST]::LOCAL_MACHINE}
        "ENTERPRISE" {return [PsUtils.CredMan+CRED_PERSIST]::ENTERPRISE}
    }
}
#endregion

#region Dot-Sourced API
function Remove-WindowsCredential
{
<#
.Synopsis
  Deletes the specified credentials
 
.Description
  Calls Win32 CredDeleteW via [PsUtils.CredMan]::CredDelete
 
.INPUTS
  See function-level notes
 
.OUTPUTS
  0 or non-0 according to action success
  [Management.Automation.ErrorRecord] if error encountered
 
.PARAMETER Target
  Specifies the URI for which the credentials are associated
   
.PARAMETER CredType
  Specifies the desired credentials type; defaults to
  "CRED_TYPE_GENERIC"
#>


    Param
    (
        [Parameter(Mandatory=$true)][ValidateLength(1,32767)][String] $Target,
        [Parameter(Mandatory=$false)][ValidateSet("GENERIC",
                                                  "DOMAIN_PASSWORD",
                                                  "DOMAIN_CERTIFICATE",
                                                  "DOMAIN_VISIBLE_PASSWORD",
                                                  "GENERIC_CERTIFICATE",
                                                  "DOMAIN_EXTENDED",
                                                  "MAXIMUM",
                                                  "MAXIMUM_EX")][String] $CredType = "GENERIC"
    )
    
    [Int] $Results = 0
    try
    {
        $Results = [PsUtils.CredMan]::CredDelete($Target, $(Get-CredType $CredType))
    }
    catch
    {
        return $_
    }
    if(0 -ne $Results)
    {
        [String] $Msg = "Failed to delete credentials store for target '$Target'"
        [Management.ManagementException] $MgmtException = New-Object Management.ManagementException($Msg)
        [Management.Automation.ErrorRecord] $ErrRcd = New-Object Management.Automation.ErrorRecord($MgmtException, $Results.ToString("X"), $ErrorCategory[$Results], $null)
        return $ErrRcd
    }
    return $Results
}

function Get-WindowsCredentials
{
<#
.Synopsis
  Enumerates stored credentials for operating user
 
.Description
  Calls Win32 CredEnumerateW via [PsUtils.CredMan]::CredEnum
 
.INPUTS
   
 
.OUTPUTS
  [PsUtils.CredMan+Credential[]] if successful
  [Management.Automation.ErrorRecord] if unsuccessful or error encountered
 
.PARAMETER Filter
  Specifies the filter to be applied to the query
  Defaults to [String]::Empty
   
#>


    Param
    (
        [Parameter(Mandatory=$false)][AllowEmptyString()][String] $Filter = [String]::Empty
    )
    
    [PsUtils.CredMan+Credential[]] $Creds = [Array]::CreateInstance([PsUtils.CredMan+Credential], 0)
    [Int] $Results = 0
    try
    {
        $Results = [PsUtils.CredMan]::CredEnum($Filter, [Ref]$Creds)
    }
    catch
    {
        return $_
    }
    switch($Results)
    {
        0 {break}
        0x80070490 {break} #ERROR_NOT_FOUND
        default
        {
            [String] $Msg = "Failed to enumerate credentials store for user '$Env:UserName'"
            [Management.ManagementException] $MgmtException = New-Object Management.ManagementException($Msg)
            [Management.Automation.ErrorRecord] $ErrRcd = New-Object Management.Automation.ErrorRecord($MgmtException, $Results.ToString("X"), $ErrorCategory[$Results], $null)
            return $ErrRcd
        }
    }
    return $Creds
}

function Get-WindowsCredential
{
<#
.Synopsis
  Reads specified credentials for operating user
 
.Description
  Calls Win32 CredReadW via [PsUtils.CredMan]::CredRead
 
.INPUTS
 
.OUTPUTS
  [PsUtils.CredMan+Credential] if successful
  [Management.Automation.ErrorRecord] if unsuccessful or error encountered
 
.PARAMETER Target
  Specifies the URI for which the credentials are associated
  If not provided, the username is used as the target
   
.PARAMETER CredType
  Specifies the desired credentials type; defaults to
  "CRED_TYPE_GENERIC"
#>


    Param
    (
        [Parameter(Mandatory=$true)][ValidateLength(1,32767)][String] $Target,
        [Parameter(Mandatory=$false)][ValidateSet("GENERIC",
                                                  "DOMAIN_PASSWORD",
                                                  "DOMAIN_CERTIFICATE",
                                                  "DOMAIN_VISIBLE_PASSWORD",
                                                  "GENERIC_CERTIFICATE",
                                                  "DOMAIN_EXTENDED",
                                                  "MAXIMUM",
                                                  "MAXIMUM_EX")][String] $CredType = "GENERIC"
    )
    
    if("GENERIC" -ne $CredType -and 337 -lt $Target.Length) #CRED_MAX_DOMAIN_TARGET_NAME_LENGTH
    {
        [String] $Msg = "Target field is longer ($($Target.Length)) than allowed (max 337 characters)"
        [Management.ManagementException] $MgmtException = New-Object Management.ManagementException($Msg)
        [Management.Automation.ErrorRecord] $ErrRcd = New-Object Management.Automation.ErrorRecord($MgmtException, 666, 'LimitsExceeded', $null)
        return $ErrRcd
    }
    [PsUtils.CredMan+Credential] $Cred = New-Object PsUtils.CredMan+Credential
    [Int] $Results = 0
    try
    {
        $Results = [PsUtils.CredMan]::CredRead($Target, $(Get-CredType $CredType), [Ref]$Cred)
    }
    catch
    {
        return $_
    }
    
    switch($Results)
    {
        0 {break}
        0x80070490 {return $null} #ERROR_NOT_FOUND
        default
        {
            [String] $Msg = "Error reading credentials for target '$Target' from '$Env:UserName' credentials store"
            [Management.ManagementException] $MgmtException = New-Object Management.ManagementException($Msg)
            [Management.Automation.ErrorRecord] $ErrRcd = New-Object Management.Automation.ErrorRecord($MgmtException, $Results.ToString("X"), $ErrorCategory[$Results], $null)
            return $ErrRcd
        }
    }
    return $Cred
}

function Add-WindowsCredential
{
<#
.Synopsis
  Saves or updates specified credentials for operating user
 
.Description
  Calls Win32 CredWriteW via [PsUtils.CredMan]::CredWrite
 
.INPUTS
 
.OUTPUTS
  [Boolean] true if successful
  [Management.Automation.ErrorRecord] if unsuccessful or error encountered
 
.PARAMETER Target
  Specifies the URI for which the credentials are associated
  If not provided, the username is used as the target
   
.PARAMETER UserName
  Specifies the name of credential to be read
   
.PARAMETER Password
  Specifies the password of credential to be read
   
.PARAMETER Comment
  Allows the caller to specify the comment associated with
  these credentials
   
.PARAMETER CredType
  Specifies the desired credentials type; defaults to
  "CRED_TYPE_GENERIC"
 
.PARAMETER CredPersist
  Specifies the desired credentials storage type;
  defaults to "CRED_PERSIST_ENTERPRISE"
#>


    Param
    (
        [Parameter(Mandatory=$false)][ValidateLength(0,32676)][String] $Target,
        [Parameter(Mandatory=$true)][ValidateLength(1,512)][String] $UserName,
        [Parameter(Mandatory=$true)][ValidateLength(1,512)][String] $Password,
        [Parameter(Mandatory=$false)][ValidateLength(0,256)][String] $Comment = [String]::Empty,
        [Parameter(Mandatory=$false)][ValidateSet("GENERIC",
                                                  "DOMAIN_PASSWORD",
                                                  "DOMAIN_CERTIFICATE",
                                                  "DOMAIN_VISIBLE_PASSWORD",
                                                  "GENERIC_CERTIFICATE",
                                                  "DOMAIN_EXTENDED",
                                                  "MAXIMUM",
                                                  "MAXIMUM_EX")][String] $CredType = "GENERIC",
        [Parameter(Mandatory=$false)][ValidateSet("SESSION",
                                                  "LOCAL_MACHINE",
                                                  "ENTERPRISE")][String] $CredPersist = "ENTERPRISE"
    )

    if([String]::IsNullOrEmpty($Target))
    {
        $Target = $UserName
    }
    if("GENERIC" -ne $CredType -and 337 -lt $Target.Length) #CRED_MAX_DOMAIN_TARGET_NAME_LENGTH
    {
        [String] $Msg = "Target field is longer ($($Target.Length)) than allowed (max 337 characters)"
        [Management.ManagementException] $MgmtException = New-Object Management.ManagementException($Msg)
        [Management.Automation.ErrorRecord] $ErrRcd = New-Object Management.Automation.ErrorRecord($MgmtException, 666, 'LimitsExceeded', $null)
        return $ErrRcd
    }
    if([String]::IsNullOrEmpty($Comment))
    {
        $Comment = [String]::Format("Last edited by {0}\{1} on {2}",
                                    $Env:UserDomain,
                                    $Env:UserName,
                                    $Env:ComputerName)
    }
    [String] $DomainName = [Net.NetworkInformation.IPGlobalProperties]::GetIPGlobalProperties().DomainName
    [PsUtils.CredMan+Credential] $Cred = New-Object PsUtils.CredMan+Credential
    switch($Target -eq $UserName -and 
           ("CRED_TYPE_DOMAIN_PASSWORD" -eq $CredType -or 
            "CRED_TYPE_DOMAIN_CERTIFICATE" -eq $CredType))
    {
        $true  {$Cred.Flags = [PsUtils.CredMan+CRED_FLAGS]::USERNAME_TARGET}
        $false  {$Cred.Flags = [PsUtils.CredMan+CRED_FLAGS]::NONE}
    }
    $Cred.Type = Get-CredType $CredType
    $Cred.TargetName = $Target
    $Cred.UserName = $UserName
    $Cred.AttributeCount = 0
    $Cred.Persist = Get-CredPersist $CredPersist
    $Cred.CredentialBlobSize = [Text.Encoding]::Unicode.GetBytes($Password).Length
    $Cred.CredentialBlob = $Password
    $Cred.Comment = $Comment

    [Int] $Results = 0
    try
    {
        $Results = [PsUtils.CredMan]::CredWrite($Cred)
    }
    catch
    {
        return $_
    }

    if(0 -ne $Results)
    {
        [String] $Msg = "Failed to write to credentials store for target '$Target' using '$UserName', '$Password', '$Comment'"
        [Management.ManagementException] $MgmtException = New-Object Management.ManagementException($Msg)
        [Management.Automation.ErrorRecord] $ErrRcd = New-Object Management.Automation.ErrorRecord($MgmtException, $Results.ToString("X"), $ErrorCategory[$Results], $null)
        return $ErrRcd
    }
    return $Results
}


# Workaround to allow Powershell to accept untrusted certificates
add-type @"
    using System.Net;
    using System.Security.Cryptography.X509Certificates;
    public class TrustAllCertsPolicy : ICertificatePolicy {
       public bool CheckValidationResult(
            ServicePoint srvPoint, X509Certificate certificate,
            WebRequest request, int certificateProblem) {
            return true;
        }
    }
"@


# OCI 7.2 only supports TLS 1.2 and PowerShell does not auto negotiate it, thus enforcing TLS 1.2 which works for older OCI Versions as well
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
 
# Using .NET JSON Serializer as JSON serialization included in Invoke-RestMethod has a length restriction for JSON content
Add-Type -AssemblyName System.Web.Extensions
$global:javaScriptSerializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer
$global:javaScriptSerializer.MaxJsonLength = [System.Int32]::MaxValue
$global:javaScriptSerializer.RecursionLimit = 99

<#
.SYNOPSIS
Add OCI Credential to the Windows Credential Store
.DESCRIPTION
Add OCI Credential to the Windows Credential Store
.EXAMPLE
Add-OciCredential
.PARAMETER Name
The name of the OCI Server.
.PARAMETER Credential
A System.Management.Automation.PSCredential object containing the credentials needed to log into the OCI server.
#>

function Add-OciCredential {
    [CmdletBinding()]
 
    PARAM (
        [parameter( Mandatory=$True,
                    Position=0,
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True,
                    HelpMessage="The name of the OCI Server.")][String[]]$Name,
        [parameter( Mandatory=$True,
                    Position=1,
                    HelpMessage="A System.Management.Automation.PSCredential object containing the credentials needed to log into the OCI server.")][System.Management.Automation.PSCredential]$Credential
    )

    Process {
        foreach ($Target in $Name) {
            $null = Add-WindowsCredential -Target $Target -UserName $Credential.UserName -Password ($Credential.Password | ConvertFrom-SecureString) -Comment 'OnCommand-Insight'
        }
    }
}

<#
.SYNOPSIS
Get OCI Credential from the Windows Credential Store
.DESCRIPTION
Get OCI Credential from the Windows Credential Store
.EXAMPLE
Get-OciCredential
.PARAMETER Name
The name of the OCI Server.
#>

function Get-OciCredential {
    [CmdletBinding()]
 
    PARAM (
        [parameter( Mandatory=$True,
                    Position=0,
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True,
                    HelpMessage="The name of the OCI Server.")][String[]]$Name
    )

    Begin {
        $Result = $null
    }

    Process {
        $Name = @($Name)
        foreach ($Target in $Name) {
            $WindowsCredential = Get-WindowsCredential -Target $Target
            if ($WindowsCredential) {
                $Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList @($WindowsCredential.UserName,($WindowsCredential.CredentialBlob | ConvertTo-SecureString))
                $Result = [PSCustomObject]@{Name=$Target;Credential=$Credential}
                Write-Output $Result
            }
            else {
                Write-Warning "No Credential found for $Target"
            }
        }
    }
}

function Get-OciCredentials {
    [CmdletBinding()]

    PARAM ()
 
    $WindowsCredentials = Get-WindowsCredentials | ? { $_.Comment -eq 'OnCommand-Insight' }

    foreach ($WindowsCredential in $WindowsCredentials) {
        if ($WindowsCredential) {
            $Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList @($WindowsCredential.UserName,($WindowsCredential.CredentialBlob | ConvertTo-SecureString))
            $Name = ($WindowsCredential.TargetName -replace '.*target=','')
            $Result = [PSCustomObject]@{Name=$Name;Credential=$Credential}
            Write-Output $Result
        }
    }
}

function Remove-OciCredential {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                   Position=0,
                   HelpMessage="The name of the OCI Server. This value may also be a string representation of an IP address. If not an address, the name must be resolvable to an address.")][String]$Name
    )

    $null = Remove-WindowsCredential -Target $Name
}

# Function for multipart upload (based on http://blog.majcica.com/2016/01/13/powershell-tips-and-tricks-multipartform-data-requests/)
function global:Invoke-MultipartFormDataUpload
{
    [CmdletBinding()]
    PARAM
    (
        [string][parameter(Mandatory = $true)][ValidateNotNullOrEmpty()]$InFile,
        [string]$ContentType,
        [Uri][parameter(Mandatory = $true)][ValidateNotNullOrEmpty()]$Uri,
        [PSObject]$Header
    )
    BEGIN
    {
        if (-not (Test-Path $InFile))
        {
            $errorMessage = ("File {0} missing or unable to read." -f $InFile)
            $exception =  New-Object System.Exception $errorMessage
            $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, 'MultipartFormDataUpload', ([System.Management.Automation.ErrorCategory]::InvalidArgument), $InFile
            $PSCmdlet.ThrowTerminatingError($errorRecord)
        }

        if (-not $ContentType)
        {
            Add-Type -AssemblyName System.Web

            $mimeType = [System.Web.MimeMapping]::GetMimeMapping($InFile)
            
            if ($mimeType)
            {
                $ContentType = $mimeType
            }
            else
            {
                $ContentType = "application/octet-stream"
            }
        }
    }
    PROCESS
    {
        Add-Type -AssemblyName System.Net.Http

        $httpClientHandler = New-Object System.Net.Http.HttpClientHandler

        $httpClient = New-Object System.Net.Http.Httpclient $httpClientHandler

        if ($Header.Authorization) {
            $httpClient.DefaultRequestHeaders.Authorization = $Header.Authorization
        }

        # set HTTP Client Timeout to a large value - e.g. 24 hours (in microsecends) to prevent timeout during upload and following processing of data (e.g. restore)
        $httpClient.Timeout = 864000000000

        $packageFileStream = New-Object System.IO.FileStream @($InFile, [System.IO.FileMode]::Open)
        
        $contentDispositionHeaderValue = New-Object System.Net.Http.Headers.ContentDispositionHeaderValue "form-data"
        $contentDispositionHeaderValue.Name = "backupFile"
        $contentDispositionHeaderValue.FileName = (Split-Path $InFile -leaf)

        $contentDispositionHeaderValue

        $streamContent = New-Object System.Net.Http.StreamContent $packageFileStream
        $streamContent.Headers.ContentDisposition = $contentDispositionHeaderValue
        $streamContent.Headers.ContentType = New-Object System.Net.Http.Headers.MediaTypeHeaderValue $ContentType
        
        $content = New-Object System.Net.Http.MultipartFormDataContent
        $content.Add($streamContent)

        try
        {
            Write-Host "Starting upload"
            $response = $httpClient.PostAsync($Uri, $content).Result

            if (!$response.IsSuccessStatusCode)
            {
                $responseBody = $response.Content.ReadAsStringAsync().Result
                $errorMessage = "Status code {0}. Reason {1}. Server reported the following message: {2}." -f $response.StatusCode, $response.ReasonPhrase, $responseBody

                throw [System.Net.Http.HttpRequestException] $errorMessage
            }

            return $response.Content.ReadAsStringAsync().Result
        }
        catch [Exception]
        {
            $PSCmdlet.ThrowTerminatingError($_)
        }
        finally
        {
            if($null -ne $httpClient)
            {
                $httpClient.Dispose()
            }

            if($null -ne $response)
            {
                $response.Dispose()
            }
        }
    }
    END { }
}
 
# Functions necessary to parse JSON output from .NET serializer to PowerShell Objects
function ParseItem($jsonItem) {
    if($jsonItem.PSObject.TypeNames -match "Array") {
        return ParseJsonArray($jsonItem)
    }
    elseif($jsonItem.PSObject.TypeNames -match "Dictionary") {
        return ParseJsonObject([HashTable]$jsonItem)
    }
    else {
        return $jsonItem
    }
}
 
function ParseJsonObject($jsonObj) {
    $result = New-Object -TypeName PSCustomObject
    foreach ($key in $jsonObj.Keys) {
        $item = $jsonObj[$key]
        if ($item) {
            $parsedItem = ParseItem $item
        } else {
            $parsedItem = $null
        }
        $result | Add-Member -MemberType NoteProperty -Name $key -Value $parsedItem
    }
    return $result
}
 
function ParseJsonArray($jsonArray) {
    $result = @()
    $jsonArray | ForEach-Object {
        $result += ,(ParseItem $_)
    }
    return $result
}
 
function ParseJsonString($json) {
    $config = $javaScriptSerializer.DeserializeObject($json)
    if ($config -is [Array]) {
        return ParseJsonArray($config)       
    }
    else {
        return ParseJsonObject($config)
    }
}

# helper function to convert datetime to unix timestamp
function ConvertTo-UnixTimestamp {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True,
                    HelpMessage="Date to be converted.")][DateTime[]]$Date
    )

    BEGIN {
        $epoch = Get-Date -Year 1970 -Month 1 -Day 1 -Hour 0 -Minute 0 -Second 0  
    }

    PROCESS {
        $Date = @($Date)

        foreach ($Date in $Date) {
                $milliSeconds = [math]::truncate($Date.ToUniversalTime().Subtract($epoch).TotalMilliSeconds)
                Write-Output $milliSeconds
        }    
    } 
}
 
# helper function to convert unix timestamp to datetime
function ConvertFrom-UnixTimestamp {
    [CmdletBinding()]

    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True,
                    HelpMessage="Timestamp to be converted.")][String]$Timestamp,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Optional Timezone to be used as basis for Timestamp. Default is system Timezone.")][System.Timezone]$Timezone=[timezone]::CurrentTimeZone
    )

    PROCESS {
        $Timestamp = @($Timestamp)
        foreach ($Timestamp in $Timestamp) {
            $Date = $Timezone.ToLocalTime(([datetime]'1/1/1970').AddMilliseconds($Timestamp))
            Write-Output $Date
        }
    }
}

function ParseExceptionBody($Response) {
    if ($Response) {
        $Reader = New-Object System.IO.StreamReader($Response.GetResponseStream())
        $Reader.BaseStream.Position = 0
        $Reader.DiscardBufferedData()
        $ResponseBody = $reader.ReadToEnd()
        if ($ResponseBody.StartsWith('{')) {
            $ResponseBody = $ResponseBody | ConvertFrom-Json | ConvertTo-Json
        }
        return $ResponseBody
    }
    else {
        return $Response
    }
}

function ParseAcquisitionUnits($AcquisitionUnits) {
    $AcquisitionUnits = @($AcquisitionUnits)
    foreach ($AcquisitionUnit in $AcquisitionUnits) {
        if ($AcquisitionUnit.nextLeaseRenewal) {
            $AcquisitionUnit.nextLeaseRenewal = $AcquisitionUnit.nextLeaseRenewal | Get-Date
        }

        if ($AcquisitionUnit.lastReported) {
            $AcquisitionUnit.lastReported = $AcquisitionUnit.lastReported | Get-Date
        }

        if ($AcquisitionUnit.datasources) {
            $AcquisitionUnit.datasources = ParseDatasources($AcquisitionUnit.datasources)
        } 
        Write-Output $AcquisitionUnit
    }
}

function ParseActivePatches($ActivePatches) {
    $ActivePatches = @($ActivePatches)
    foreach ($ActivePatch in $ActivePatches) {
        if ($ActivePatch.createTime) {
            $ActivePatch.createTime = $ActivePatch.createTime | Get-Date
        }
        if ($ActivePatch.lastUpdateTime) {
            $ActivePatch.lastUpdateTime = $ActivePatch.lastUpdateTime | Get-Date
        }

        Write-Output $ActivePatch
    }
}

function ParseDatasources($Datasources) {
    $Datasources = @($Datasources)
    foreach ($Datasource in $Datasources) {
        if ($Datasource.lastSuccessfullyAcquired) {
            $Datasource.lastSuccessfullyAcquired = $Datasource.lastSuccessfullyAcquired | Get-Date
        }

        if ($Datasource.resumeTime) {
            $Datasource.resumeTime = $Datasource.resumeTime | Get-Date
        }
        if ($Datasource.AcquisitionUnit) {
            $Datasource.AcquisitionUnit = ParseAcquisitionUnits($Datasource.AcquisitionUnit)
        }
        if ($Datasource.Changes) {
            $Datasource.Changes = ParseChanges($Datasource.Changes)
        }
        if ($Datasource.Events) {
            $Datasource.Events = ParseEvents($Datasource.Events)
        }
        if ($Datasource.activePatch) {
            $Datasource.activePatch = ParseActivePatches($Datasource.activePatch)
        }
        Write-Output $Datasource
    }
}

function ParseChanges($Changes) {
    $Changes = @($Changes)
    foreach ($Change in $Changes) {
        if ($Change.time) {
            $Change.time = $Change.time | Get-Date
        }

        Write-Output $Change
    }
}

function ParseEvents($Events) {
    $Events = @($Events)
    foreach ($Event in $Events) {
        if ($Event.StartTime) {
            $Event.StartTime = $Event.StartTime | Get-Date
        }
        if ($Event.EndTime) {
            $Event.EndTime = $Event.EndTime | Get-Date
        }

        Write-Output $Event
    }
}

function ParseCertificates($Certificates) {
    $Certificates = @($Certificates)
    foreach ($Certificate in $Certificates) {
        if ($Certificate.ExpirationDate) {
            $Certificate.ExpirationDate = $Certificate.ExpirationDate | Get-Date
        }

        Write-Output $Certificate
    }
}

function ParseLicenseStatus($LicenseStatus) {
    $LicenseStatus.LicenseParts = ParseLicenses($LicenseStatus.LicenseParts)

    Write-Output $LicenseStatus
}

function ParseLicenses($Licenses) {
    $Licenses = @($Licenses)
    foreach ($License in $Licenses) {
        if ($License.ExpirationDate) {
            $License.ExpirationDate = $License.ExpirationDate | Get-Date
        }

        Write-Output $License
    }
}

function ParseUsers($Users) {
    $Users = @($Users)
    foreach ($User in $Users) {
        if ($User.lastLogin) {
            $User.lastLogin = $User.lastLogin | Get-Date
        }

        Write-Output $User
    }
}

function ParseDatastores($Datastores) {
    $Datastores = @($Datastores)
    foreach ($Datastore in $Datastores) {
        if ($Datastore.performance) {
            $Datastore.performance = ParsePerformance($Datastore.performance)
        }

        Write-Output $Datastore
    }
}

function ParsePerformance($Performance) {
    if ($Performance.accessed) {
        $Performance.accessed.start = $Performance.accessed.start | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
        $Performance.accessed.end = $Performance.accessed.end | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
    }
    if ($Performance.iops) {
        $Performance.iops.read.start = $Performance.iops.read.start | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
        $Performance.iops.read.end = $Performance.iops.read.end | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
        $Performance.iops.write.start = $Performance.iops.write.start | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
        $Performance.iops.write.end = $Performance.iops.write.end | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
        $Performance.iops.totalMax.start = $Performance.iops.totalMax.start | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
        $Performance.iops.totalMax.end = $Performance.iops.totalMax.end | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
        $Performance.iops.total.start = $Performance.iops.total.start | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
        $Performance.iops.total.end = $Performance.iops.total.end | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
    }
    if ($Performance.cacheHitRatio) {
        $Performance.cacheHitRatio.read.start = $Performance.cacheHitRatio.read.start | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
        $Performance.cacheHitRatio.read.end = $Performance.cacheHitRatio.read.end | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
        $Performance.cacheHitRatio.write.start = $Performance.cacheHitRatio.write.start | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
        $Performance.cacheHitRatio.write.end = $Performance.cacheHitRatio.write.end | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
        $Performance.cacheHitRatio.total.start = $Performance.cacheHitRatio.total.start | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
        $Performance.cacheHitRatio.total.end = $Performance.cacheHitRatio.total.end | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
    }
    if ($Performance.latency) {
        $Performance.latency.read.start = $Performance.latency.read.start | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
        $Performance.latency.read.end = $Performance.latency.read.end | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
        $Performance.latency.write.start = $Performance.latency.write.start | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
        $Performance.latency.write.end = $Performance.latency.write.end | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
        $Performance.latency.total.start = $Performance.latency.total.start | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
        $Performance.latency.total.end = $Performance.latency.total.end | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
        $Performance.latency.totalMax.start = $Performance.latency.totalMax.start | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
        $Performance.latency.totalMax.end = $Performance.latency.totalMax.end | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
    }
    if ($Performance.partialBlocksRatio.total) {
        $Performance.partialBlocksRatio.total.start = $Performance.partialBlocksRatio.total.start | ? { $_ } | ConvertFrom-UnixTimestamp
        $Performance.partialBlocksRatio.total.end = $Performance.partialBlocksRatio.total.end | ? { $_ } | ConvertFrom-UnixTimestamp
    }
    if ($Performance.writePending.total) {
        $Performance.writePending.total.start = $Performance.writePending.total.start | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
        $Performance.writePending.total.end = $Performance.writePending.total.end | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
    }
    if ($Performance.throughput) {
        $Performance.throughput.read.start = $Performance.throughput.read.start | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
        $Performance.throughput.read.end = $Performance.throughput.read.end | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
        $Performance.throughput.write.start = $Performance.throughput.write.start | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
        $Performance.throughput.write.end = $Performance.throughput.write.end | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
        $Performance.throughput.totalMax.start = $Performance.throughput.totalMax.start | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
        $Performance.throughput.totalMax.end = $Performance.throughput.totalMax.end | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
        $Performance.throughput.total.start = $Performance.throughput.total.start | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
        $Performance.throughput.total.end = $Performance.throughput.total.end | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone
    }
    if ($Performance.history) {
        $Performance.history = ParsePerformanceHistory($Performance.history)
    }

    Write-Output $Performance
}

function ParsePerformanceHistory($PerformanceHistory) {
    if ($PerformanceHistory[0].count -eq 2) {
        $PerformanceHistory = foreach ($entry in $PerformanceHistory) {
            if ($entry[1]) {
                $entry[1] | Add-Member -MemberType NoteProperty -Name timestamp -Value ($entry[0] | ? { $_ } | ConvertFrom-UnixTimestamp -Timezone $Server.Timezone) -PassThru
            }
        }
    }
    Write-Output $PerformanceHistory
} 

function ParseVirtualMachines($VirtualMachines) {
    $VirtualMachines = @($VirtualMachines)
    foreach ($VirtualMachine in $VirtualMachines) {
        if ($VirtualMachine.createTime) {
            $VirtualMachine.createTime = $VirtualMachine.createTime | Get-Date
        }
        if ($VirtualMachine.performance) {
            $VirtualMachine.performance = ParsePerformance($VirtualMachine.performance)
        }
        if ($VirtualMachine.vmdks) {
            $VirtualMachine.vmdks = ParseVmdks($VirtualMachine.vmdks)
        }
        if ($VirtualMachine.host) {
            $VirtualMachine.host = ParseHosts($VirtualMachine.host)
        }
        if ($VirtualMachine.ports) {
            $VirtualMachine.ports = ParsePorts($VirtualMachine.ports)
        }
        if ($VirtualMachine.dataStore) {
            $VirtualMachine.dataStore = ParseDatastores($VirtualMachine.dataStore)
        }
        if ($VirtualMachine.applications) {
            $VirtualMachine.applications = ParseApplications($VirtualMachine.applications)
        }
        if ($VirtualMachine.fileSystems) {
            $VirtualMachine.fileSystems = ParseFileSystems($VirtualMachine.fileSystems)
        }
        if ($VirtualMachine.storageResources) {
            $VirtualMachine.storageResources = ParseStorageResources($VirtualMachine.storageResources)
        }
        if ($VirtualMachine.annotations) {
            $VirtualMachine.annotations = ParseAnnotations($VirtualMachine.annotations)
        }
        if ($VirtualMachine.datasources) {
            $VirtualMachine.datasources = ParseDatasources($VirtualMachine.datasources)
        }

        Write-Output $VirtualMachine
    }
}

function ParseVmdks($Vmdks) {
    $Vmdks = @($Vmdks)
    foreach ($Vmdk in $Vmdks) {
        if ($vmdk.dataStore) {
            $vmdk.dataStore = ParseDatastores($vmdk.dataStore)
        }
        if ($vmdk.virtualMachine) {
            $vmdk.virtualMachine = ParseVirtualMachines($vmdk.virtualMachine)
        }
        if ($vmdk.performance) {
            $vmdk.performance = ParsePerformance($vmdk.performance)
        }
        if ($vmdk.storageResources) {
            $vmdk.storageResources = ParseStorageResources($vmdk.storageResources)
        }
        if ($vmdk.annotations) {
            $vmdk.annotations = ParseAnnotations($vmdk.annotations)
        }
        if ($vmdk.datasources) {
            $vmdk.datasources = ParseDatasources($vmdk.datasources)
        }

        Write-Output $vmdk
    }
}

function ParseHosts($Hosts) {
    $Hosts = @($Hosts)
    foreach ($Host in $Hosts) {
        if ($Host.createTime) {
            $Host.createTime = $Host.createTime | Get-Date
        }
        if ($Host.performance) {
            $Host.performance = ParsePerformance($Host.performance)
        }
        if ($Host.storageResources) {
            $Host.storageResources = ParseStorageResources($Host.storageResources)
        }
        if ($Host.fileSystems) {
            $Host.fileSystems = ParseFileSystems($Host.fileSystems)
        }
        if ($Host.ports) {
            $Host.ports = ParsePorts($Host.ports)
        }
        if ($Host.applications) {
            $Host.applications = ParseApplications($Host.applications)
        }
        if ($Host.virtualMachines) {
            $Host.virtualMachines = ParseVirtualMachines($Host.virtualMachines)
        }
        if ($Host.clusterHosts) {
            $Host.clusterHosts = ParseHosts($Host.clusterHosts)
        }
        if ($Host.annotations) {
            $Host.annotations = ParseAnnotations($Host.annotations)
        }
        if ($Host.datasources) {
            $Host.datasources = ParseDatasources($Host.datasources)
        }

        Write-Output $Host
    }
}

function ParsePorts($Ports) {
    $Ports = @($Ports)
    foreach ($Port in $Ports) {
        if ($Port.performance) {
            $Port.performance = ParsePerformance($Port.performance)
        }
        if ($Port.device) {
            $Port.device = ParseDevice($Port.device)
        }
        if ($Port.fabrics) {
            $Port.fabrics = ParseFabrics($Port.fabrics)
        }
        if ($Port.annotations) {
            $Port.annotations = ParseAnnotations($Port.annotations)
        }
        if ($Port.datasources) {
            $Port.datasources = ParseDatasources($Port.datasources)
        }
        if ($Port.application) {
            $Port.application = ParseApplication($Port.application)
        }

        Write-Output $Port
    }
}

function ParseApplications($Applications) {
    $Applications = @($Applications)
    foreach ($Application in $Applications) {

        Write-Output $Application
    }
}

function ParseAnnotations($Annotations) {
    $Annotations = @($Annotations)
    foreach ($Annotation in $Annotations) {

        Write-Output $Annotation
    }
}

function ParseComputeResources($ComputeResources) {
    $ComputeResources = @($ComputeResources)
    foreach ($ComputeResource in $ComputeResources) {
        if ($ComputeResource.createTime) {
            $ComputeResource.createTime = $ComputeResource.createTime | Get-Date
        }
        if ($ComputeResource.performance) {
            $ComputeResource.performance = ParsePerformance($ComputeResource.performance)
        }
        if ($ComputeResource.storageResources) {
            $ComputeResource.storageResources = ParseStorageResources($ComputeResource.storageResources)
        }
        if ($ComputeResource.fileSystems) {
            $ComputeResource.fileSystems = ParseFileSystems($ComputeResource.fileSystems)
        }
        if ($ComputeResource.ports) {
            $ComputeResource.ports = ParsePorts($ComputeResource.ports)
        }
        if ($ComputeResource.applications) {
            $ComputeResource.applications = ParseApplications($ComputeResource.applications)
        }
        if ($ComputeResource.virtualMachines) {
            $ComputeResource.virtualMachines = ParseVirtualMachines($ComputeResource.virtualMachines)
        }
        if ($ComputeResource.clusterHosts) {
            $ComputeResource.clusterHosts = ParseHosts($ComputeResource.clusterHosts)
        }
        if ($ComputeResource.annotations) {
            $ComputeResource.annotations = ParseAnnotations($ComputeResource.annotations)
        }
        if ($ComputeResource.datasources) {
            $ComputeResource.datasources = ParseDatasources($ComputeResource.datasources)
        }

        Write-Output $ComputeResource
    }
}

function ParseStorageResources($StorageResources) {
    $StorageResources = @($StorageResources)
    foreach ($StorageResource in $StorageResources) {
        if ($StorageResource.createTime) {
            $StorageResource.createTime = $StorageResource.createTime | Get-Date
        }
        if ($StorageResource.performance) {
            $StorageResource.performance = ParsePerformance($StorageResource.performance)
        }
        if ($StorageResource.computeResources) {
            $StorageResource.computeResources = ParseComputeResources($StorageResource.computeResources)
        }
        if ($StorageResource.fileSystems) {
            $StorageResource.fileSystems = ParseFileSystems($StorageResource.fileSystems)
        }
        if ($StorageResource.storagePools) {
            $StorageResource.storagePools = ParseStoragePools($StorageResource.storagePools)
        }
        if ($StorageResource.applications) {
            $StorageResource.applications = ParseApplications($StorageResource.applications)
        }
        if ($StorageResource.virtualMachines) {
            $StorageResource.virtualMachines = ParseVirtualMachines($StorageResource.virtualMachines)
        }
        if ($StorageResource.annotations) {
            $StorageResource.annotations = ParseAnnotations($StorageResource.annotations)
        }
        if ($StorageResource.datasources) {
            $StorageResource.datasources = ParseDatasources($StorageResource.datasources)
        }

        Write-Output $StorageResource
    }
}

function ParseStoragePools($StoragePools) {
    $StoragePools = @($StoragePools)
    foreach ($StoragePool in $StoragePools) {
        if ($StoragePool.performance) {
            $StoragePool.performance = ParsePerformance($StoragePool.performance)
        }
        if ($StoragePool.storage) {
            $StoragePool.storage = ParseStorages($StoragePool.storage)
        }
        if ($StoragePool.disks) {
            $StoragePool.disks = ParseDisks($StoragePool.disks)
        }
        if ($StoragePool.storageResources) {
            $StoragePool.storageResources = ParseStorageResources($StoragePool.storageResources)
        }
        if ($StoragePool.internalVolumes) {
            $StoragePool.internalVolumes = ParseInternalVolumes($StoragePool.internalVolumes)
        }
        if ($StoragePool.volumes) {
            $StoragePool.volumes = ParseVolumes($StoragePool.volumes)
        }
        if ($StoragePool.storageNodes) {
            $StoragePool.storageNodes = ParseStorageNodes($StoragePool.storageNodes)
        }
        if ($StoragePool.datasources) {
            $StoragePool.datasources = ParseDatasources($StoragePool.datasources)
        }
        if ($StoragePool.annotations) {
            $StoragePool.annotations = ParseAnnotations($StoragePool.annotations)
        }

        Write-Output $StoragePool
    }
}

<#
.EXAMPLE
Connect-OciServer -Name ociserver.example.com -Credential (Get-Credential)
 
Name : ociserver.example.com
BaseURI : https://ociserver.example.com
Credential : System.Management.Automation.PSCredential
Headers : {Authorization}
APIVersion : 1.2
Timezone : System.CurrentSystemTimeZone
#>

function global:Connect-OciServer {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                   Position=0,
                   HelpMessage="The name of the OCI Server. This value may also be a string representation of an IP address. If not an address, the name must be resolvable to an address.")][String]$Name,
        [parameter(Mandatory=$False,
                   Position=1,
                   HelpMessage="A System.Management.Automation.PSCredential object containing the credentials needed to log into the OCI server.")][System.Management.Automation.PSCredential]$Credential,
        [parameter(Mandatory=$False,
                   Position=2,
                   HelpMessage="This cmdlet always tries to establish a secure HTTPS connection to the OCI server, but it will fall back to HTTP if necessary. Specify -HTTP to skip the HTTPS connection attempt and only try HTTP.")][Switch]$HTTP,
        [parameter(Mandatory=$False,
                   Position=2,
                   HelpMessage="This cmdlet always tries to establish a secure HTTPS connection to the OCI server, but it will fall back to HTTP if necessary. Specify -HTTPS to fail the connection attempt in that case rather than fall back to HTTP.")][Switch]$HTTPS,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="If the OCI server certificate cannot be verified, the connection will fail. Specify -Insecure to ignore the validity of the OCI server certificate.")][Switch]$Insecure,
        [parameter(Position=4,
                   Mandatory=$False,
                   HelpMessage="Specify -Transient to not set the global variable `$CurrentOciServer.")][Switch]$Transient,
        [parameter(Mandatory=$False,
                   Position=5,
                   HelpMessage="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.")][PSObject]$Timezone,
        [parameter(Mandatory=$False,
                   Position=6,
                   HelpMessage="Timeout value for HTTP connections. Defaults to 600 seconds.")][Int]$Timeout
    )

    if (!$Credential) {
        $Credential = Get-OciCredential -Name $Name | Select-Object -ExpandProperty Credential
        if (!$Credential) {
            throw "No Credentials supplied and $Name not in list of known OCI Servers"
        }
    }
 
    # Issue with jBoss see http://alihamdar.com/2010/06/19/expect-100-continue/
    [System.Net.ServicePointManager]::Expect100Continue = $false
 
    $EncodedAuthorization = [System.Text.Encoding]::UTF8.GetBytes($Credential.UserName + ':' + $Credential.GetNetworkCredential().Password)
    $EncodedPassword = [System.Convert]::ToBase64String($EncodedAuthorization)
    $Headers = @{"Authorization"="Basic $($EncodedPassword)"}
 
    # check if untrusted SSL certificates should be ignored
    if ($Insecure) {
        [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
    }

    # check if proxy is used
    $ProxyRegistry = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
    $ProxySettings = Get-ItemProperty -Path $ProxyRegistry
    if ($ProxySettings.ProxyEnable) {
        Write-Warning "Proxy Server $($ProxySettings.ProxyServer) configured in Internet Explorer may be used to connect to the OCI server!"
    }
    if ($ProxySettings.AutoConfigURL) {
        Write-Warning "Proxy Server defined in automatic proxy configuration script $($ProxySettings.AutoConfigURL) configured in Internet Explorer may be used to connect to the OCI server!"
    }
 
    if ($HTTPS -or !$HTTP) {
        Try {
            $BaseURI = "https://$Name"
            $Response = Invoke-RestMethod -Method Post -Uri "$BaseURI/rest/v1/login" -TimeoutSec $Timeout -Headers $Headers
            $APIVersion = $Response.apiVersion
        }
        Catch {
            $ResponseBody = ParseExceptionBody $_.Exception.Response
            if ($_.Exception.Message -match "Unauthorized") {
                Write-Error "Authorization for $BaseURI/rest/v1/login with user $($Credential.UserName) failed"
                return
            }
            else {
                if ($HTTPS) {
                    Write-Error "Login to $BaseURI/rest/v1/login failed via HTTPS protocol, but HTTPS was enforced. Exception $($_.Exception.Message)`n $ResponseBody"
                    return
                }
                else {
                    Write-Warning "Login to $BaseURI/rest/v1/login failed via HTTPS protocol. Exception message: $($_.Exception.Message)`n $ResponseBody"
                    $HTTP = $True
                }
            }
        }
    }

    if ($HTTP) {
        Try {
            $BaseURI = "http://$Name"
            $Response = Invoke-RestMethod -Method Post -Uri "$BaseURI/rest/v1/login" -TimeoutSec $Timeout -Headers $Headers
            $APIVersion = $Response.apiVersion
        }
        Catch {
            $ResponseBody = ParseExceptionBody $_.Exception.Response
            if ($_.Exception.Message -match "Unauthorized") {                
                Write-Error "Authorization for $BaseURI/rest/v1/login with user $($Credential.UserName) failed"
                return
            }
            else {
                Write-Error "Login to $BaseURI/rest/v1/login failed via HTTP protocol. Exception message: $($_.Exception.Message)`n $ResponseBody"
                return
            }
        }
    }

    if (!$Timezone) {
        $Timezone = [timezone]::CurrentTimeZone
    }
    
    if ($Timezone -isnot [Timezone]) {
        if ([System.TimeZoneInfo]::GetSystemTimeZones().Id -contains $Timezone) {
            $Timezone = [System.TimeZoneInfo]::GetSystemTimeZones() | ? { $_.Id -contains $Timezone }
        }
        else {
            $Timezone = [timezone]::CurrentTimeZone
        }
    }

    if (!$Timeout) {
        $Timeout = 600
    }
 
    $Server = New-Object -TypeName psobject
    $Server | Add-Member -MemberType NoteProperty -Name Name -Value $Name
    $Server | Add-Member -MemberType NoteProperty -Name BaseURI -Value $BaseURI
    $Server | Add-Member -MemberType NoteProperty -Name Credential -Value $Credential
    $Server | Add-Member -MemberType NoteProperty -Name Headers -Value $Headers
    $Server | Add-Member -MemberType NoteProperty -Name APIVersion -Value $APIVersion
    $Server | Add-Member -MemberType NoteProperty -Name Timezone -Value $Timezone
    $Server | Add-Member -MemberType NoteProperty -Name Timeout -Value $Timeout
 
    if (!$Transient) {
        Set-Variable -Name CurrentOciServer -Value $Server -Scope Global
    }
 
    return $Server
}

<#
    .SYNOPSIS
    Retrieve all Acquisition Units
    .DESCRIPTION
    Retrieve all Acquisition Units
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=datasources)
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciAcquisitionUnits {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                    Position=0,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=datasources)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                   Position=2,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $Uri = $Server.BaseUri + "/rest/v1/admin/acquisitionUnits"
  
        $switchparameters=@("datasources")
        foreach ($parameter in $switchparameters) {
            if ((Get-Variable $parameter).Value) {
                if ($expand) {
                    $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                }
                else {
                    $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                }
            }
        }

        if ($expand) {
            $Uri += "?expand=$expand"
        }

        try {
            $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
        }
        catch {
            $ResponseBody = ParseExceptionBody $_.Exception.Response
            Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
        }
 
        if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
            $Result = ParseJsonString($Result.Trim())
        }

        $AcquisitionUnits = ParseAcquisitionUnits($Result)
        Write-Output $AcquisitionUnits
    }
}

<#
    .SYNOPSIS
    Retrieve one Acquisition Unit
    .DESCRIPTION
    Retrieve one Acquisition Unit
    .PARAMETER id
    Id of acquisition unit to retrieve
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=datasources)
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciAcquisitionUnit {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of acquisition unit to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=datasources)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $($Server.BaseUri) + "/rest/v1/admin/acquisitionUnits/$id"
 
           
            $switchparameters=@("datasources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($expand) {
                $Uri += "?$($Separator)expand=$expand"
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            $AcquisitionUnit = ParseAcquisitionUnits($Result)
            Write-Output $AcquisitionUnit
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all datasources of an acquisition unit
    .DESCRIPTION
    Retrieve all datasources of an acquisition unit
    .PARAMETER id
    ID of acquisition unit to get datasources for
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=datasources)
    .PARAMETER acquisitionUnit
    Return related Acquisition unit
    .PARAMETER note
    Return related Note
    .PARAMETER changes
    Return list of related Changes
    .PARAMETER packages
    Return list of related Packages
    .PARAMETER activePatch
    Return related Active patch
    .PARAMETER events
    Return list of related Events
    .PARAMETER devices
    Return list of related Devices
    .PARAMETER config
    Return related Config
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciDatasourcesByAcquisitionUnit {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="ID of acquisition unit to get datasources for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=datasources)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return related Acquisition unit")][Switch]$acquisitionUnit,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Return related Note")][Switch]$note,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related Changes")][Switch]$changes,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Packages")][Switch]$packages,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return related Active patch")][Switch]$activePatch,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Events")][Switch]$events,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Devices")][Switch]$devices,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return related Config")][Switch]$config,
        [parameter(Mandatory=$False,
                   Position=10,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/acquisitionUnits/$id/datasources"

            $switchparameters=@("acquisitionUnit","note","changes","packages","activePatch","events","devices","config")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($expand) {
                $Uri += "?$($Separator)expand=$expand"
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            $Datasources = ParseDatasources($Result)
            Write-Output $Datasources
        }
    }
}

<#
    .SYNOPSIS
    Restart an Acquisition Unit
    .DESCRIPTION
    Restart an Acquisition Unit
    .PARAMETER id
    ID of acquisition unit to restart
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Restart-OciAcquisitionUnit {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of acquisition unit to restart",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                   Position=1,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/acquisitionUnits/$id/restart"
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "POST to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
       
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve list of certificates
    .DESCRIPTION
    Retrieve list of certificates
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciCertificates {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                   Position=0,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/certificates"
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
       
            $Certificates = ParseCertificates($Result)
            Write-Output $Certificates
        }
    }
}


# TODO: Check and implement uploading of certificates
<#
    .SYNOPSIS
    Add a certificate based on source host/port or certificate file
    .DESCRIPTION
    User can add certificate for LDAP based on either source host/port or certificate file. Two ways to create certificate are supported: <br/>

To create from host and port use:
<pre>
{
    "host": "localhost",
    "port": 389
}
</pre>

To create from existing certificate file create a multi part request with the attributes:
<pre>
    alias: the alias for certificate in store
    certificateFile: the actual file to load into store
</pre>
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Add-OciCertificate {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                   Position=0,
                   HelpMessage="OnCommand Insight Server.")]$Alias,
        [parameter(Mandatory=$True,
                   Position=1,
                   ParameterSetName='host',
                   HelpMessage="OnCommand Insight Server.")]$Host,
        [parameter(Mandatory=$True,
                   Position=2,
                   ParameterSetName='host',
                   HelpMessage="OnCommand Insight Server.")]$Port='389',
        [parameter(Mandatory=$True,
                   Position=1,
                   ParameterSetName='file',
                   HelpMessage="OnCommand Insight Server.")]$File,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/certificates"
 
           
            $switchparameters=@("")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                if ('POST' -match 'PUT|POST') {
                    Write-Verbose "Body: "
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers -Body "" -ContentType 'application/json'
                }
                else {
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers
                }
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "POST to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
       
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all data source types.
    .DESCRIPTION
    Retrieve all data source types.
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciDatasourceTypes {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                   Position=0,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $Uri = $Server.BaseUri + "/rest/v1/admin/datasourceTypes"
 
        try {
            $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
        }
        catch {
            $ResponseBody = ParseExceptionBody $_.Exception.Response
            Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
        }
 
        if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
            $Result = ParseJsonString($Result.Trim())
        }
       
        Write-Output $Result
    }
}

<#
    .SYNOPSIS
    Retrieve one data source type.
    .DESCRIPTION
    Retrieve one data source type.
    .PARAMETER id
    ID of data source type
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciDatasourceType {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                   Position=0,
                   HelpMessage="Id of data source type",
                   ValueFromPipeline=$True,
                   ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                   Position=1,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/datasourceTypes/$id"      
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all Data Sources
    .DESCRIPTION
    Retrieve all Data Sources
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=acquisitionUnit)
    .PARAMETER acquisitionUnit
    Return related Acquisition unit
    .PARAMETER note
    Return related Note
    .PARAMETER changes
    Return list of related Changes
    .PARAMETER packages
    Return list of related Packages
    .PARAMETER activePatch
    Return related Active patch
    .PARAMETER events
    Return list of related Events
    .PARAMETER devices
    Return list of related Devices
    .PARAMETER config
    Return related Config
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciDatasources {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                    Position=0,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=acquisitionUnit)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related Acquisition unit")][Switch]$acquisitionUnit,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return related Note")][Switch]$note,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Return list of related Changes")][Switch]$changes,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related Packages")][Switch]$packages,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Active patch")][Switch]$activePatch,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Events")][Switch]$events,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Devices")][Switch]$devices,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return related Config")][Switch]$config,
        [parameter(Mandatory=$False,
                   Position=9,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/datasources"

            $switchparameters=@("acquisitionUnit","note","changes","packages","activePatch","events","devices","config")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($expand) {
                $Uri += "?$($Separator)expand=$expand"
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            $Datasources = ParseDatasources($Result)
            Write-Output $Datasources
        }
    }
}

# TODO: Implement and test adding of datasoure
<#
    .SYNOPSIS
    Add Data Source
    .DESCRIPTION
    Request payload for new datasource should contain JSON in the format that is obtained by using following expands on GET one datasource: acquisitionUnit,config<br/>
<pre>
    {
      "name": "datasource_name",
      "acquisitionUnit": {
        "id": "1"
      },
      "config": {
        "vendor": "VMware",
        "model": "vSphere (Web Services)",
        "packages":
        [
          {
            "id": "foundation",
            "attributes":
            {
              "ip": "127.0.0.0"
            }
          }
        ]
      }
    }
</pre>
    .PARAMETER acquisitionUnit
    Return related Acquisition unit
    .PARAMETER note
    Return related Note
    .PARAMETER changes
    Return list of related Changes
    .PARAMETER packages
    Return list of related Packages
    .PARAMETER activePatch
    Return related Active patch
    .PARAMETER events
    Return list of related Events
    .PARAMETER devices
    Return list of related Devices
    .PARAMETER config
    Return related Config
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Add-OciDatasource {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                    Position=0,
                    HelpMessage="Return related Acquisition unit")][Switch]$acquisitionUnit,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related Note")][Switch]$note,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Changes")][Switch]$changes,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Return list of related Packages")][Switch]$packages,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Active patch")][Switch]$activePatch,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Events")][Switch]$events,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Devices")][Switch]$devices,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return related Config")][Switch]$config
    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/datasources"
 
           
            $switchparameters=@("acquisitionUnit","note","changes","packages","activePatch","events","devices","config")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                if ('POST' -match 'PUT|POST') {
                    Write-Verbose "Body: "
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers -Body "" -ContentType 'application/json'
                }
                else {
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers
                }
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "POST to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

# TODO: Test deletion of datasoure
<#
    .SYNOPSIS
    Remove a Datasource
    .DESCRIPTION
    Remove a Datasource
    .PARAMETER id
    Id of data source to remove
    .PARAMETER acquisitionUnit
    Return related Acquisition unit
    .PARAMETER note
    Return related Note
    .PARAMETER changes
    Return list of related Changes
    .PARAMETER packages
    Return list of related Packages
    .PARAMETER activePatch
    Return related Active patch
    .PARAMETER events
    Return list of related Events
    .PARAMETER devices
    Return list of related Devices
    .PARAMETER config
    Return related Config
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Remove-OciDatasource {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of data source to remove",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                   Position=1,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/datasources/$id"
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve a DataSource
    .DESCRIPTION
    Retrieve a DataSource
    .PARAMETER id
    Id of data source to retrieve
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=acquisitionUnit)
    .PARAMETER acquisitionUnit
    Return related Acquisition unit
    .PARAMETER note
    Return related Note
    .PARAMETER changes
    Return list of related Changes
    .PARAMETER packages
    Return list of related Packages
    .PARAMETER activePatch
    Return related Active patch
    .PARAMETER events
    Return list of related Events
    .PARAMETER devices
    Return list of related Devices
    .PARAMETER config
    Return related Config
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciDatasource {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of data source to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=acquisitionUnit)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return related Acquisition unit")][Switch]$acquisitionUnit,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Return related Note")][Switch]$note,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related Changes")][Switch]$changes,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Packages")][Switch]$packages,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return related Active patch")][Switch]$activePatch,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Events")][Switch]$events,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Devices")][Switch]$devices,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return related Config")][Switch]$config,
        [parameter(Mandatory=$False,
                   Position=10,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/datasources/$id"
 
            $switchparameters=@("acquisitionUnit","note","changes","packages","activePatch","events","devices","config")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($expand) {
                $Uri += "?$($Separator)expand=$expand"
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
       
            $Datasource = ParseDatasources($Result)
            Write-Output $Datasource
        }
    }
}

# TODO: Implement and test updating of DataSource
<#
    .SYNOPSIS
    Update one DataSource.
    .DESCRIPTION
    Request payload for datasource to be updated should contain JSON in the format that is obtained by using following expands on GET one datasource: acquisitionUnit,config <br/>
<pre>
    {
      "name": "datasource_name",
      "acquisitionUnit": {
        "id": "1"
      },
      "config": {
        "packages":
        [
          {
            "id": "foundation",
            "attributes":
            {
              "ip": "127.0.0.0"
            }
          }
        ]
      }
    }
</pre>
             
    .PARAMETER id
    Id of data source to update
    .PARAMETER acquisitionUnit
    Return related Acquisition unit
    .PARAMETER note
    Return related Note
    .PARAMETER changes
    Return list of related Changes
    .PARAMETER packages
    Return list of related Packages
    .PARAMETER activePatch
    Return related Active patch
    .PARAMETER events
    Return list of related Events
    .PARAMETER devices
    Return list of related Devices
    .PARAMETER config
    Return related Config
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Update-OciDataSource {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of data source to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related Acquisition unit")][Switch]$acquisitionUnit,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return related Note")][Switch]$note,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Return list of related Changes")][Switch]$changes,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related Packages")][Switch]$packages,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Active patch")][Switch]$activePatch,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Events")][Switch]$events,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Devices")][Switch]$devices,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return related Config")][Switch]$config,
        [parameter(Mandatory=$False,
                   Position=9,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/datasources/$id"

            $switchparameters=@("acquisitionUnit","note","changes","packages","activePatch","events","devices","config")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PATCH -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PATCH to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieves Acquisition Unit by datasource.
    .DESCRIPTION
    Retrieves Acquisition Unit by datasource.
    .PARAMETER id
    Id of datasource for which to retrieve acquisition unit
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=acquisitionUnit)
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciAcquisitionUnitByDatasource {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of datasource for which to retrieve acquisition unit",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=acquisitionUnit)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                   Position=2,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $($Server.BaseUri) + "/rest/v1/admin/datasources/$id/acquisitionUnit"

            $switchparameters=@("datasources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($expand) {
                $Uri += "?$($Separator)expand=$expand"
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            $AcquisitionUnit = ParseAcquisitionUnits($Result)
           
            Write-Output $AcquisitionUnit
        }
    }
}

<#
    .SYNOPSIS
    Retrieves the active patch for a data source
    .DESCRIPTION
    Retrieves the active patch for a data source
    .PARAMETER id
    Id of data source to find active patch
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER datasourceConclusions
    Return list of related Patched datasources status
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciActivePatchByDatasource {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of data source to find active patch",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Patched datasources status")][Switch]$datasourceConclusions,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/datasources/$id/activePatch"
 
            $switchparameters=@("datasourceConclusions")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($expand) {
                $Uri += "?$($Separator)expand=$expand"
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            $ActivePatch = ParseActivePatches($Result)
            Write-Output $ActivePatch
        }
    }
}

<#
    .SYNOPSIS
    Retrieve Data Source changes
    .DESCRIPTION
    Retrieve Data Source changes
    .PARAMETER id
    Id of data source to get data for
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER details
    Return list of related Details
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciDatasourceChanges {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of data source to get data for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Details")][Switch]$details,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/datasources/$id/changes"
 
            $switchparameters=@("details")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 

            if ($expand) {
                $Uri += "?$($Separator)expand=$expand"
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            $Change = ParseChanges($Result)
            Write-Output $Change
        }
    }
}

<#
    .SYNOPSIS
    Retrieve Datasource configuration.
    .DESCRIPTION
    Retrieve Datasource configuration.
    .PARAMETER id
    Id of data source to retrieve configuration for
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciDatasourceConfiguration {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of data source to retrieve configuration for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                   Position=1,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/datasources/$id/config"
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve datasource devices
    .DESCRIPTION
    Retrieve datasource devices
    .PARAMETER id
    Id of data source to get devices for
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciDatasourceDevices {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of data source to get devices for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                   Position=1,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/datasources/$id/devices"
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve Data Source events (audits)
    .DESCRIPTION
    Retrieve Data Source events (audits)
    .PARAMETER id
    Id of data source to get data for
    .PARAMETER details
    Return event details
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciDatasourceEvents {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of data source to get data for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return event details")][Switch]$details,
        [parameter(Mandatory=$False,
                   Position=2,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/datasources/$id/events"
 
            $switchparameters=@("details")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($expand) {
                $Uri += "?$($Separator)expand=$expand"
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve Datasource event details
    .DESCRIPTION
    Retrieve Datasource event details
    .PARAMETER id
    Id of data source event to get data for
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciDatasourceEventDetails {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of data source event to get data for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                   Position=1,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/datasources/events/$id/details"
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
          
            $Events = ParseEvents($Result)
            Write-Output $Events
        }
    }
}

<#
    .SYNOPSIS
    Retrieve DataSource note
    .DESCRIPTION
    Retrieve DataSource note
    .PARAMETER id
    Id of data source to retrieve note for
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciDatasourceNote {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of data source to retrieve note for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                   Position=1,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/datasources/$id/note"
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
          
            Write-Output $Result
        }
    }
}

# TODO: Check and implement updating of datasource note
<#
    .SYNOPSIS
    Update one Data Source note
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>
{
    "value":"My Note"
}
</pre>
             
    .PARAMETER id
    Id of data source to update
    .PARAMETER value
    Note to be added to datasource
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Update-OciDatasourceNote {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of data source to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$True,
                    Position=1,
                    HelpMessage="Note to be added to datasource")][String]$value
    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/datasources/$id/note"
 
            $switchparameters=@("")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                if ('PUT' -match 'PUT|POST') {
                    Write-Verbose "Body: {`"value`":$value}"
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PUT -Uri $Uri -Headers $Server.Headers -Body "{`"value`":$value}" -ContentType 'application/json'
                }
                else {
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PUT -Uri $Uri -Headers $Server.Headers
                }
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PUT to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve DataSource package status
    .DESCRIPTION
    Retrieve DataSource package status
    .PARAMETER id
    Id of data source to get package status for
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciDatasourcePackageStatus {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of data source to get data for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                   Position=1,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/datasources/$id/packages"
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
          
            Write-Output $Result
        }
    }
}

# TODO: Implement polling of datasources
<#
    .SYNOPSIS
    Poll one Data Source
    .DESCRIPTION
    Empty POST body
    .PARAMETER id
    Id of data source to poll
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Poll-OciDatasource {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of data source to poll",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id
    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/datasources/$id/poll"
 
           
            $switchparameters=@("")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                if ('POST' -match 'PUT|POST') {
                    Write-Verbose "Body: "
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers -Body "" -ContentType 'application/json'
                }
                else {
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers
                }
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "POST to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

# TODO: Implement / Check suspending of datasources
<#
    .SYNOPSIS
    Postpone one Data Source
    .DESCRIPTION
    Input body: { "days": value }
    .PARAMETER id
    Id of data source to postpone
    .PARAMETER Days
    Number of days to postpone datasource polling
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Suspend-OciDatasource {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of data source to postpone",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$True,
                    Position=1,
                    HelpMessage="Number of days to postpone datasource polling")][Long]$Days
    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/datasources/$id/postpone"
 
           
            $switchparameters=@("")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                if ('POST' -match 'PUT|POST') {
                    Write-Verbose "Body: {`"days`":$days}"
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers -Body "{`"days`":$days}" -ContentType 'application/json'
                }
                else {
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers
                }
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "POST to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

# TODO: Implement / Test resuming of datasources
<#
    .SYNOPSIS
    Resume one Data Source
    .DESCRIPTION
    Empty POST body
    .PARAMETER id
    Id of data source to resume
#>

function Global:Resume-OciDatasource {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of data source to resume",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id
    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/datasources/$id/resume"
 
           
            $switchparameters=@("")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                if ('POST' -match 'PUT|POST') {
                    Write-Verbose "Body: "
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers -Body "" -ContentType 'application/json'
                }
                else {
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers
                }
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "POST to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

# TODO: Implement / Test testing of datasources
<#
    .SYNOPSIS
    Test Data Source
    .DESCRIPTION
    Empty POST body
    .PARAMETER id
    Id of data source to test
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Test-OciDatasource {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of data source to test",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id
    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/datasources/$id/test"
 
           
            $switchparameters=@("")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                if ('POST' -match 'PUT|POST') {
                    Write-Verbose "Body: "
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers -Body "" -ContentType 'application/json'
                }
                else {
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers
                }
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "POST to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve LDAP configuration
    .DESCRIPTION
    Retrieve LDAP configuration
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciLdapConfiguration {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                   Position=0,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/ldap"
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
          
            Write-Output $Result
        }
    }
}

# TODO: Implement / Test updating o ldap configuration
<#
    .SYNOPSIS
    Update LDAP config
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>
{
    "isEnabled": true,
    "directoryLookup": {
        "server": "ldap://localhost",
        "timeout": 1000,
        "referral": "follow",
        "userName": "directoryLookupUserName",
        "password": "directoryLookupUserPassword",
        "domain": "DC=domain,DC=com"
    },
    "groups": {
        "users": "insight.users",
        "guests": "insight.guests",
        "admins": "insight.admins",
        "serverAdmins": "insight.server.admins"
    },
    "attributes": {
        "role": "memberOf",
        "mail": "mail",
        "userPrincipalName": "userPrincipalName",
        "distinguishedName": "distinguishedName"
    }
}
</pre>
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Update-OciLdapConfiguration {
    [CmdletBinding()]
 
    PARAM (

    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/ldap"
 
           
            $switchparameters=@("")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                if ('PUT' -match 'PUT|POST') {
                    Write-Verbose "Body: "
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PUT -Uri $Uri -Headers $Server.Headers -Body "" -ContentType 'application/json'
                }
                else {
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PUT -Uri $Uri -Headers $Server.Headers
                }
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PUT to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

# TODO: Implement / Test LDAP connection test
<#
    .SYNOPSIS
    Perform an LDAP connection test
    .DESCRIPTION
    Request body to include information on LDAP server and credentials to test. Request body should be like JSON below: <br/>

<pre>
{
  "server": "ldap://localhost",
  "userName": "user",
  "password": "password"
}
</pre>
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Test-OciLdapConfiguration {
    [CmdletBinding()]
 
    PARAM (

    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/ldap/test"
 
           
            $switchparameters=@("")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                if ('POST' -match 'PUT|POST') {
                    Write-Verbose "Body: "
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers -Body "" -ContentType 'application/json'
                }
                else {
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers
                }
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "POST to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve license status
    .DESCRIPTION
    Retrieve license status
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciLicenseStatus {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                   Position=0,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $Uri = $Server.BaseUri + "/rest/v1/admin/license"
 
        try {
            $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
        }
        catch {
            $ResponseBody = ParseExceptionBody $_.Exception.Response
            Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
        }
 
        if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
            $Result = ParseJsonString($Result.Trim())
        }

        $LicenseStatus = ParseLicenseStatus($Result)
           
        Write-Output $LicenseStatus
    }
}

# Todo: Implement / Test Updating of licenses
<#
    .SYNOPSIS
    Update license information
    .DESCRIPTION
    Request body should be list of license keys, example: <br/>

<pre>
[
    "TEST1234567890LicenceKey1",
    "TEST1234567890LicenceKey2"
]
</pre>
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Update-OciLicenses {
    [CmdletBinding()]
 
    PARAM (

    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/license"
 
           
            $switchparameters=@("")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                if ('PATCH' -match 'PUT|POST') {
                    Write-Verbose "Body: "
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PATCH -Uri $Uri -Headers $Server.Headers -Body "" -ContentType 'application/json'
                }
                else {
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PATCH -Uri $Uri -Headers $Server.Headers
                }
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PATCH to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

# TODO: Implement / Test replacing of licenses
<#
    .SYNOPSIS
    Replace license information
    .DESCRIPTION
    Request body should be list of license keys, example:<br/>

<pre>
    [
        "TEST1234567890LicenceKey1",
        "TEST1234567890LicenceKey2"
    ]
</pre>
             
 
#>

function Global:Replace-OciLicense {
    [CmdletBinding()]
 
    PARAM (

    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/license"
 
           
            $switchparameters=@("")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                if ('POST' -match 'PUT|POST') {
                    Write-Verbose "Body: "
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers -Body "" -ContentType 'application/json'
                }
                else {
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers
                }
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "POST to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all patches
    .DESCRIPTION
    Retrieve all patches
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER datasourceConclusions
    Return related datasource status
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciPatches {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                    Position=0,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related datasource status")][Switch]$datasourceConclusions,
        [parameter(Mandatory=$False,
                   Position=2,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $Uri = $Server.BaseUri + "/rest/v1/admin/patches"

        $switchparameters=@("datasourceConclusions")
        foreach ($parameter in $switchparameters) {
            if ((Get-Variable $parameter).Value) {
                if ($expand) {
                    $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                }
                else {
                    $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                }
            }
        }
 
        if ($expand) {
            $Uri += "?$($Separator)expand=$expand"
        }
 
        try {
            $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
        }
        catch {
            $ResponseBody = ParseExceptionBody $_.Exception.Response
            Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
        }
 
        if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
            $Result = ParseJsonString($Result.Trim())
        }
           
        Write-Output $Result
    }
}

# TODO: Implement / Test adding of patches
<#
    .SYNOPSIS
    Add Patch
    .DESCRIPTION
    POST request to include 'patchFile' file parameter
    .PARAMETER datasourceConclusions
    Return list of related Patched datasources status
#>

function Global:Add-OciPatches {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                    Position=0,
                    HelpMessage="Return list of related Patched datasources status")][Switch]$datasourceConclusions
    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/patches"
 
           
            $switchparameters=@("datasourceConclusions")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                if ('POST' -match 'PUT|POST') {
                    Write-Verbose "Body: "
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers -Body "" -ContentType 'application/json'
                }
                else {
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers
                }
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "POST to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Get patch
    .DESCRIPTION
    Get patch
    .PARAMETER id
    Id of a patch to retrieve
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER datasourceConclusions
    Return list of related Patched datasources status
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciPatch {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of a patch to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Patched datasources status")][Switch]$datasourceConclusions,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/patches/$id"
 
            $switchparameters=@("datasourceConclusions")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($expand) {
                $Uri += "?$($Separator)expand=$expand"
            }
 
            try {               
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
          
            Write-Output $Result
        }
    }
}

# TODO: Implement / Test updating of patch
<#
    .SYNOPSIS
    Update one patch
    .DESCRIPTION
    POST request to include 'patchFile' file parameter
    .PARAMETER id
    Id of patch to update
    .PARAMETER datasourceConclusions
    Return list of related Patched datasources status
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Update-OciPatch {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of patch to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return list of related Patched datasources status")][Switch]$datasourceConclusions
    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/patches/$id"
 
           
            $switchparameters=@("datasourceConclusions")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                if ('POST' -match 'PUT|POST') {
                    Write-Verbose "Body: "
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers -Body "" -ContentType 'application/json'
                }
                else {
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers
                }
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "POST to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

# TODO: Implement / test approving of patch
<#
    .SYNOPSIS
    Approve one patch
    .DESCRIPTION
    Empty body
    .PARAMETER id
    Id of patch to approve
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Approve-OciPatch {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of patch to approve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id
    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/patches/$id/approve"
 
           
            $switchparameters=@("")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                if ('POST' -match 'PUT|POST') {
                    Write-Verbose "Body: "
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers -Body "" -ContentType 'application/json'
                }
                else {
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers
                }
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "POST to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve Patch Data Source Conclusions
    .DESCRIPTION
    Retrieve Patch Data Source Conclusions
    .PARAMETER id
    Id of patch to get data source conslusions for
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciPatchDatasourceConclusions {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of patch to get data source conslusions for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                   Position=2,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/patches/$id/datasourceConclusions"
 
            if ($expand) {
                $Uri += "?$($Separator)expand=$expand"
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

# TODO: Implement / Test updating of patch note
<#
    .SYNOPSIS
    Update one patch note
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>
{
    "value": "My Note"
}
</pre>
                 
    .PARAMETER id
    Id of patch to update
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Update-OciPatchNote {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of patch to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id
    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/patches/$id/note"
 
           
            $switchparameters=@("")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                if ('PUT' -match 'PUT|POST') {
                    Write-Verbose "Body: "
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PUT -Uri $Uri -Headers $Server.Headers -Body "" -ContentType 'application/json'
                }
                else {
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PUT -Uri $Uri -Headers $Server.Headers
                }
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PUT to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

# TODO: Implement / Test rollback of patch
<#
    .SYNOPSIS
    Rollback one patch
    .DESCRIPTION
    Empty body
    .PARAMETER id
    Id of patch to rolback
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Rollback-OciPatch {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of patch to rolback",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id
    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/patches/$id/rollback"
 
           
            $switchparameters=@("")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                if ('POST' -match 'PUT|POST') {
                    Write-Verbose "Body: "
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers -Body "" -ContentType 'application/json'
                }
                else {
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers
                }
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "POST to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all users
    .DESCRIPTION
    Retrieve all users
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciUsers {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                   Position=0,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $Uri = $Server.BaseUri + "/rest/v1/admin/users"

        try {
            $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
        }
        catch {
            $ResponseBody = ParseExceptionBody $_.Exception.Response
            Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
        }
 
        if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
            $Result = ParseJsonString($Result.Trim())
        }

        $Users = ParseUsers($Result)
        Write-Output $Users
    }
}

# TODO: Implement / Test creation of new user
<#
    .SYNOPSIS
    Create a new user
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>
{
    "name":"test",
    "password": "pwd",
    "email": "email@test.com",
    "insightRole": "USER",
    "isActive": false
}
</pre>
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Add-OciUsers {
    [CmdletBinding()]
 
    PARAM (

    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/users"
 
           
            $switchparameters=@("")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                if ('POST' -match 'PUT|POST') {
                    Write-Verbose "Body: "
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers -Body "" -ContentType 'application/json'
                }
                else {
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers
                }
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "POST to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve currently logged in user
    .DESCRIPTION
    Retrieve currently logged in user
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciCurrentUser {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                   Position=0,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $Uri = $Server.BaseUri + "/rest/v1/admin/users/current"
 
        try {
            $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
        }
        catch {
            $ResponseBody = ParseExceptionBody $_.Exception.Response
            Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
        }
 
        if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
            $Result = ParseJsonString($Result.Trim())
        }
        
        $User = ParseUsers($Result)
        Write-Output $User
    }
}

# TODO: Implement / Test deletion of user
<#
    .SYNOPSIS
    Delete one user
    .DESCRIPTION
     
    .PARAMETER id
    The id of user to delete
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Delete-OciUser {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="The id of user to delete",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                   Position=1,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/users/$id"
 
           
            $switchparameters=@("")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                if ('DELETE' -match 'PUT|POST') {
                    Write-Verbose "Body: "
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers -Body "" -ContentType 'application/json'
                }
                else {
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers
                }
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve one user
    .DESCRIPTION
    Retrieve one user
    .PARAMETER id
    The id of user to retrieve
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciUser {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="The id of user to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                   Position=1,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/users/$id"
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            $User = ParseUsers($Result)
            Write-Output $User
        }
    }
}

# TODO: Implement / Test updating of users
<#
    .SYNOPSIS
    Update one user
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>
{
    "password": "pwd",
    "email": "email@test.com",
    "insightRole": "USER",
    "isActive": false
}
</pre>
             
    .PARAMETER id
    The id of user to update
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Update-OciUser {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="The id of user to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id
    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/users/$id"
 
           
            $switchparameters=@("")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                if ('PUT' -match 'PUT|POST') {
                    Write-Verbose "Body: "
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PUT -Uri $Uri -Headers $Server.Headers -Body "" -ContentType 'application/json'
                }
                else {
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PUT -Uri $Uri -Headers $Server.Headers
                }
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PUT to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all annotation definitions
    .DESCRIPTION
    Retrieve all annotation definitions
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciAnnotations {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                   Position=1,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $Uri = $Server.BaseUri + "/rest/v1/assets/annotations"
 
        try {
            $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
        }
        catch {
            $ResponseBody = ParseExceptionBody $_.Exception.Response
            Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
        }
 
        if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
            $Result = ParseJsonString($Result.Trim())
        }
           
        Write-Output $Result
    }
}

# TODO: Implement / Test creation of annotation definitions
<#
    .SYNOPSIS
    Create annotation definition
    .DESCRIPTION
    Request body should include required name, type, optional description and enumValues (if enum type). Enums should contain name and label. Example: <br/>
<pre>
{
    "name": "StorageLocation",
    "type": "FIXED_ENUM",
    "description": "Storage Location",
    "enumValues": [
        {
          "name": "PT_LISBON",
          "label": "Lisbon (Portugal)"
        },
        {
          "name": "US_WALTHAM",
          "label": "Waltham (USA)"
        }
    ]
}
</pre>
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Create-OciAnnotationDefinition {
    [CmdletBinding()]
 
    PARAM (

    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/annotations"
 
           
            $switchparameters=@("")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                if ('POST' -match 'PUT|POST') {
                    Write-Verbose "Body: "
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers -Body "" -ContentType 'application/json'
                }
                else {
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers
                }
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "POST to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

# TODO: Implement / Test deletion of annotation definitions
<#
    .SYNOPSIS
    Delete annotation definition by id or name
    .DESCRIPTION
    Delete annotation definition by id or name
    .PARAMETER id
    Id or name of annotation definition to delete
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Remove-OciDefinition {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id or name of annotation definition to delete",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][String[]]$id
    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/annotations/$id"
 
           
            $switchparameters=@("")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                if ('DELETE' -match 'PUT|POST') {
                    Write-Verbose "Body: "
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers -Body "" -ContentType 'application/json'
                }
                else {
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers
                }
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve annotation definition
    .DESCRIPTION
    Retrieve annotation definition
    .PARAMETER id
    Id or name of annotation definition to retrieve
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciAnnotation {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id or name of annotation definition to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][String[]]$id,
        [parameter(Mandatory=$False,
                   Position=1,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/annotations/$id"
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            $Annotation = ParseAnnotations($Result)
            Write-Output $Annotation
        }
    }
}

# TODO: Implement / Test updating of annotations
<#
    .SYNOPSIS
    Update annotation definition by id or name
    .DESCRIPTION
    Request body could include optional name, description, enum values. Enums should contain name and label. Example: <br/>

<pre>
{
    "name": "MyStorageLocation",
    "description": "My Storage Location",
    "enumValues": [
        {
          "name": "PT_LISBON",
          "label": "Lisbon (Portugal)"
        },
        {
          "name": "US_WALTHAM",
          "label": "Waltham (USA)"
        },
        {
          "name": "US_SUNNYVALE",
          "label": "Sunnyvale (USA)"
        }
    ]
}
</pre>
         
    .PARAMETER id
    Id or name of annotation definition to update
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Update-OciDefinition {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id or name of annotation definition to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][String[]]$id
    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/annotations/$id"
 
           
            $switchparameters=@("")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                if ('PATCH' -match 'PUT|POST') {
                    Write-Verbose "Body: "
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PATCH -Uri $Uri -Headers $Server.Headers -Body "" -ContentType 'application/json'
                }
                else {
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PATCH -Uri $Uri -Headers $Server.Headers
                }
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PATCH to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

# TODO: Implement / Test removing of annotation definitions
<#
    .SYNOPSIS
    Remove object annotations in bulk by annotation definition
    .DESCRIPTION
    'targets' in response contains target object IDs. Request body should be like JSON below: <br/>

<pre>
[
  {
    "objectType": "StoragePool",
    "targets": [
       "2052",
       "8739",
       "5926"
    ]
  }
]
</pre>
             
    .PARAMETER id
    Id or name of annotation definition to update
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Remove-OciDefinitionValues {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id or name of annotation definition to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][String[]]$id
    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/annotations/$id/values"
 
           
            $switchparameters=@("")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                if ('DELETE' -match 'PUT|POST') {
                    Write-Verbose "Body: "
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers -Body "" -ContentType 'application/json'
                }
                else {
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers
                }
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve annotation definition values for all supported object types
    .DESCRIPTION
    Retrieve annotation definition values for all supported object types
    .PARAMETER id
    Id or name of annotation definition to retrieve values for
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciAnnotationValues {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id or name of annotation definition to retrieve values for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][String[]]$id,
        [parameter(Mandatory=$False,
                   Position=1,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/annotations/$id/values"
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

# TODO: Implement / Test updating of annotation definition
<#
    .SYNOPSIS
    Update object annotations in bulk by annotation definition
    .DESCRIPTION
    'values.targets' in response contains target object IDs. Request body should be like JSON below: <br/>

<pre>
[
  {
    "objectType": "StoragePool",
    "values": [
      {
        "rawValue": "Bronze",
        "targets": [
          "11299",
          "11305"
        ]
      },
      {
        "rawValue": "Gold",
        "targets": [
          "16398",
          "8721"
        ]
      },
      {
        "rawValue": "Silver",
        "targets": [
          "26644"
        ]
      },
      {
        "rawValue": "Gold-Fast",
        "targets": [
          "2052",
          "8739",
          "5926"
        ]
      }
    ]
  }
]
</pre>
             
    .PARAMETER id
    Id or name of annotation definition to update
    .PARAMETER objectType
    Object type of objects where annotations should be added (e.g. StoragePool or InternalVolume)
    .PARAMETER rawValue
    Value of Annotation
    .PARAMETER targets
    IDs of object where annotation should be added
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Update-OciAnnotationValues {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id or name of annotation definition to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][String[]]$id,
        [parameter(Mandatory=$True,
                    Position=1,
                    HelpMessage="Object type of objects where annotations should be added (e.g. StoragePool or InternalVolume)")][String]$objectType,
        [parameter(Mandatory=$True,
                    Position=2,
                    HelpMessage="Value of Annotation")][String]$rawValue,
        [parameter(Mandatory=$True,
                    Position=3,
                    HelpMessage="IDs of object where annotation should be added")][String[]]$targets,
        [parameter(Mandatory=$False,
                   Position=1,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/annotations/$id/values"

            try {
                $Body = ConvertTo-Json @(@{objectType=$objectType;values=@(@{rawValue=$rawValue;targets=$targets})}) -Compress -Depth 4
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PUT -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PUT to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve annotation definition values for one supported object type
    .DESCRIPTION
    'targets' in response contains URLs for target objects
    .PARAMETER id
    Id or name of annotation definition to retrieve
    .PARAMETER objectType
    The object type to retrieve values for
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciAnnotationValuesByObjectType {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id or name of annotation definition to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][String[]]$id,
        [parameter(Mandatory=$True,
                    Position=1,
                    HelpMessage="The object type to retrieve values for")][String]$objectType,
        [parameter(Mandatory=$False,
                   Position=2,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/annotations/$id/values/$objectType"
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

# TODO: Implement / Test updating of annotation definitions
<#
    .SYNOPSIS
    Retrieve annotation definition targets for one supported object type, one specific value
    .DESCRIPTION
    Returns list of URLs for objects for annotation, object type, value
    .PARAMETER id
    Id or name of annotation definition to retrieve
    .PARAMETER objectType
    The object type to retrieve target objects for
    .PARAMETER value
    The specific value to retrieve target objects for
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Update-OciAnnotationValuesByObjectTypeAndValue {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id or name of annotation definition to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][String[]]$id,
        [parameter(Mandatory=$True,
                    Position=1,
                    HelpMessage="The object type to retrieve target objects for")][String]$objectType,
        [parameter(Mandatory=$True,
                    Position=2,
                    HelpMessage="The specific value to retrieve target objects for")][String]$value
    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/annotations/$id/values/{objectType}/{value}"
 
           
            $switchparameters=@("")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                if ('GET' -match 'PUT|POST') {
                    Write-Verbose "Body: "
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers -Body "" -ContentType 'application/json'
                }
                else {
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
                }
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
       
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all applications
    .DESCRIPTION
    Retrieve all applications
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciApplications {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                    Position=0,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=5,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/applications"

            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }

            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            $Applications = ParseApplications($Result)
            Write-Output $Applications
        }
    }
}

<#
    .SYNOPSIS
    Add a new application
    .DESCRIPTION
    Add a new application
    .PARAMETER name
    Name of the application
    .PARAMETER priority
    Application priority (Critical, High, Medium or Low). Default is Medium.
    .PARAMETER businessEntity
    Business entity ID to attach the application to
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Add-OciApplication {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Name of the application")][String]$name,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Application priority (Critical, High, Medium or Low). Default is Medium.")][ValidateSet("Critical", "High", "Medium", "Low")][String]$priority="Medium",
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Business entity ID to attach the application to")][String]$businessEntity,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Business entity ID to attach the application to")][Switch]$ignoreShareViolations,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=6,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }

    Process {
        $Uri = $Server.BaseUri + "/rest/v1/assets/applications"

        $switchparameters=@("computeResources","storageResources")
        foreach ($parameter in $switchparameters) {
            if ((Get-Variable $parameter).Value) {
                if ($expand) {
                    $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                }
                else {
                    $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                }
            }
        }
 
        if ($fromTime -or $toTime -or $expand) {
            $Uri += '?'
            $Separator = ''
            if ($fromTime) {
                $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                $Separator = '&'
            }
            if ($toTime) {
                $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                $Separator = '&'
            }
            if ($expand) {
                $Uri += "$($Separator)expand=$expand"
            }
        }
 
        try {
            if ($businessEntity) {
                $Body = ConvertTo-Json @{name=$name;priority=$priority;businessEntity=@{id=$businessEntity};ignoreShareViolations=$($ignoreShareViolations.IsPresent)} -Compress
            }
            else {
                $Body = ConvertTo-Json @{name=$name;priority=$priority;ignoreShareViolations=$($ignoreShareViolations.IsPresent)} -Compress
            }
            Write-Verbose "Body: $Body"
            $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
        }
        catch {
            $ResponseBody = ParseExceptionBody $_.Exception.Response
            Write-Error "POST to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
        }
 
        if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
            $Result = ParseJsonString($Result.Trim())
        }
           
        $Application = ParseApplications($Result)
        Write-Output $Application
    }
}

# TODO: Implemet / Test unassigning of applications from assets
<#
    .SYNOPSIS
    Bulk un-assign applications from assets
    .DESCRIPTION
    Request body should contain a list application ids mapped to a list of asset ids, grouped by type, example: <br/>

<pre>
[
    {
        "123": [
            {
                "objectType": "Qtree",
                "targets": [
                    "11299",
                    "11305"
                ]
            },
            {
                "objectType": "InternalVolume",
                "targets": [
                    "11299",
                    "11305"
                ]
            }
        ]
    },
    {
        "456": [
            {
                "objectType": "VirtualMachine",
                "targets": [
                    "2052",
                    "8739"
                ]
            }
        ]
    }
]
</pre>
             
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Remove-OciApplicationsFromAssets {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                    Position=0,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources
    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/applications/assets"
 
           
            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                if ('DELETE' -match 'PUT|POST') {
                    Write-Verbose "Body: "
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers -Body "" -ContentType 'application/json'
                }
                else {
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers
                }
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

# TODO: Implement / Test
<#
    .SYNOPSIS
    Bulk assign applications to assets
    .DESCRIPTION
    Request body should contain a list application ids mapped to a list of asset ids, grouped by type, example: <br/>

<pre>
[
    {
        "123": [
            {
                "objectType": "Qtree",
                "targets": [
                    "11299",
                    "11305"
                ]
            },
            {
                "objectType": "InternalVolume",
                "targets": [
                    "11299",
                    "11305"
                ]
            }
        ]
    },
    {
        "456": [
            {
                "objectType": "VirtualMachine",
                "targets": [
                    "2052",
                    "8739"
                ]
            }
        ]
    }
]
</pre>
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Add-OciApplicationsToAssets {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                    Position=0,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources
    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/applications/assets"
 
           
            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                if ('PATCH' -match 'PUT|POST') {
                    Write-Verbose "Body: "
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PATCH -Uri $Uri -Headers $Server.Headers -Body "" -ContentType 'application/json'
                }
                else {
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PATCH -Uri $Uri -Headers $Server.Headers
                }
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PATCH to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Remove an application
    .DESCRIPTION
    Remove an application
    .PARAMETER id
    Id of application to delete
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Remove-OciApplication {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of application to delete",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/applications/$id"

            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            $Application = ParseApplications($Result)
            Write-Output $Application
        }
    }
}

<#
    .SYNOPSIS
    Retrieve application
    .DESCRIPTION
    Retrieve application
    .PARAMETER id
    Id of application to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciApplication {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of application to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=6,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/applications/$id"
           
            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
            
            $Application = ParseApplications($Result)
            Write-Output $Application
        }
    }
}

<#
    .SYNOPSIS
    Update an application
    .DESCRIPTION
    Update an application
    .PARAMETER id
    Id of application to update
    .PARAMETER priority
    Application priority (Critical, High, Medium or Low). Default is Medium.
    .PARAMETER businessEntity
    Business entity ID to attach the application to
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Update-OciApplication {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of application to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Application priority (Critical, High, Medium or Low). Default is Medium.")][ValidateSet("Critical", "High", "Medium", "Low")][String]$priority="Medium",
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Business entity ID to attach the application to")][String]$businessEntity,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Business entity ID to attach the application to")][Switch]$ignoreShareViolations,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=6,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/applications/$id"
 
            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                if ($businessEntity) {
                    $Body = ConvertTo-Json @{name=$name;priority=$priority;businessEntity=@{id=$businessEntity};ignoreShareViolations=$($ignoreShareViolations.IsPresent)} -Compress
                }
                else {
                    $Body = ConvertTo-Json @{name=$name;priority=$priority;ignoreShareViolations=$($ignoreShareViolations.IsPresent)} -Compress
                }
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PUT -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PUT to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            $Application = ParseApplications($Result)
            Write-Output $Application
        }
    }
}

# TODO: Implement / Test
<#
    .SYNOPSIS
    Bulk un-assign application from assets
    .DESCRIPTION
    Request body should contain a list of asset ids, grouped by type, example: <br/>

<pre>
[
    {
        "objectType": "StoragePool"
        "targets": [
            "11299",
            "11305"
        ]
    },
    {
        "objectType": "VirtualMachine"
        "targets": [
            "2052",
            "8739"
        ]
    }
]
</pre>
             
    .PARAMETER id
    Id of application to un-assign from assets
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Bulk-OciUnAssignApplicationFromAssets {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of application to un-assign from assets",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id
    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/applications/$id/assets"
 
           
            $switchparameters=@("")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                if ('DELETE' -match 'PUT|POST') {
                    Write-Verbose "Body: "
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers -Body "" -ContentType 'application/json'
                }
                else {
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers
                }
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve assets for application
    .DESCRIPTION
    Retrieve assets for application
    .PARAMETER id
    Id of application to retrieve assets for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciAssetsByApplication {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of application to retrieve assets for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/applications/$id/assets"
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

# TODO: Implement / Test
<#
    .SYNOPSIS
    Bulk assign application to assets
    .DESCRIPTION
    Request body should contain lists of asset ids, grouped by type, example: <br/>

<pre>
[
    {
        "objectType": "Volume",
        "targets": [
            "11299",
            "11305"
        ]
    },
    {
        "objectType": "VirtualMachine",
        "targets": [
            "2052",
            "8739"
        ]
    }
]
</pre>
             
    .PARAMETER id
    Id of application to assign to assets
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Bulk-OciAssignApplicationToAssets {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of application to assign to assets",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/applications/$id/assets"
 
           
            $switchparameters=@("")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                if ('PATCH' -match 'PUT|POST') {
                    Write-Verbose "Body: "
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PATCH -Uri $Uri -Headers $Server.Headers -Body "" -ContentType 'application/json'
                }
                else {
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PATCH -Uri $Uri -Headers $Server.Headers
                }
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PATCH to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve compute resources by application
    .DESCRIPTION
    Retrieve compute resources by application
    .PARAMETER id
    Id of application to retrieve compute resources for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER performance
    Return related Performance
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER fileSystems
    Return list of related File systems
    .PARAMETER performancehistory
    Return related Performance History
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciComputeResourcesByApplication {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of application to retrieve compute resources for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related File systems")][Switch]$fileSystems,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=9,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/applications/$id/computeResources"
           
            $switchparameters=@("performance","ports","storageResources","fileSystems","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
            
            $ComputeResources = ParseComputeResources($Result)
            Write-Output $ComputeResources
        }
    }
}

<#
    .SYNOPSIS
    Retrieve storage resources by application
    .DESCRIPTION
    Retrieve storage resources by application
    .PARAMETER id
    Id of application to retrieve storage resources for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER performance
    Return related Performance
    .PARAMETER dataStores
    Return list of related Datastores
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER performancehistory
    Return related Performance History
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciStorageResourcesByApplication {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of application to retrieve storage resources for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Datastores")][Switch]$dataStores,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=11,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/applications/$id/storageResources"
 
            $switchparameters=@("storage","performance","dataStores","computeResources","applications","storagePools","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
            
            $StorageResources = ParseStorageResources($Result)
            Write-Output $StorageResources
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all business entities
    .DESCRIPTION
    Retrieve all business entities
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciBusinessEntities {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                   Position=0,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $Uri = $Server.BaseUri + "/rest/v1/assets/businessEntities"
 
        try {
            $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
        }
        catch {
            $ResponseBody = ParseExceptionBody $_.Exception.Response
            Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
        }
 
        if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
            $Result = ParseJsonString($Result.Trim())
        }
           
        Write-Output $Result
    }
}

# TODO: Implemement / Test
<#
    .SYNOPSIS
    Add a new business entity
    .DESCRIPTION
    At least one of tenant, lob, businessUnit and project in request body should have valid value. Example: <br/>

            <pre>
            {
                "tenant":"tenant1",
                "lob":"lob1",
                "businessUnit":"businessUnit1",
                "project":"project1"
            }
            </pre>
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Add-OciBusinessEntity {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                   Position=0,
                   HelpMessage="Tenant.")][String]$Tenant,
        [parameter(Mandatory=$False,
                   Position=1,
                   HelpMessage="OnCommand Insight Server.")][String]$LineOfBusiness,
        [parameter(Mandatory=$False,
                   Position=2,
                   HelpMessage="OnCommand Insight Server.")][String]$BusinessUnit,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")][String]$Project,
        [parameter(Mandatory=$False,
                   Position=4,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $Uri = $Server.BaseUri + "/rest/v1/assets/businessEntities"
 
        try {
            $Body = @{tenant=$Tenant;lob=$LineOfBusiness;businessUnit=$BusinessUnit;project=$project} | ConvertTo-Json -Compress
            Write-Verbose "Body: $Body"
            $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'            
        }
        catch {
            $ResponseBody = ParseExceptionBody $_.Exception.Response
            Write-Error "POST to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
        }
 
        if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
            $Result = ParseJsonString($Result.Trim())
        }
           
        Write-Output $Result
    }
}

# TODO: Implement / Test
<#
    .SYNOPSIS
    Delete a business entity
    .DESCRIPTION
    Delete a business entity
    .PARAMETER id
    Id of business entity to delete
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Delete-OciBusinessEntity {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of business entity to delete",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                   Position=0,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/businessEntities/$id"
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve business entity with empty fields set to N/A
    .DESCRIPTION
    Retrieve business entity with empty fields set to N/A
    .PARAMETER id
    Id of business entity to retrieve
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciBusinessEntity {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of business entity to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                   Position=1,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/businessEntities/$id"
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all datastores
    .DESCRIPTION
    Retrieve all datastores
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER sort
    Filter for sorting by performance metric/s (Default iops.total)
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER limit
    Number of datastores per page (range: 0-50, default: 0)
    .PARAMETER offset
    Offset to be used with limit
    .PARAMETER performance
    Return related Performance
    .PARAMETER hosts
    Return list of related Hosts
    .PARAMETER vmdks
    Return list of related Vmdks
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER performancehistory
    Return related Performance History
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciDatastores {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                    Position=0,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Filter for sorting by performance metric/s (Default iops.total)")][String]$sort="iops.total",
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Number of datastores per page (range: 0-50, default: 0)")][Long]$limit=0,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Offset to be used with limit")][Long]$offset=0,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Hosts")][Switch]$hosts,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Vmdks")][Switch]$vmdks,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                   Position=12,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            # OCI allows to only fetch maximum 50 items when performance data is requested, thus we need to repeat the command if no limit is specified to fetch all items
            if ($Performance -and $Limit -eq 0) {
                $FetchAll = $true
                $Limit = 50
            }

            $Uri = $($Server.BaseUri) + "/rest/v1/assets/dataStores"
 
            $switchparameters=@("performance","hosts","vmdks","datasources","storageResources","annotations")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
            
            if ($fromTime -or $toTime -or $expand -or $sort -or $limit -or $offset) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($performance -and $sort) {
                    $Uri += "$($Separator)sort=$((Get-Variable 'sort').Value)"
                    $Separator = '&'
                }
                if ($limit) {
                    $Uri += "$($Separator)limit=$((Get-Variable 'limit').Value)"
                    $Separator = '&'
                }
                if ($limit -and $offset) {
                    $Uri += "$($Separator)offset=$((Get-Variable 'offset').Value)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
            
            $Datastores = ParseDatastores($Result)
                        
            Write-Output $Datastores

            if ($FetchAll -and $Datastores.Count -eq $Limit) {
                $Offset += $Limit
                Get-OciDatastores -fromTime $fromTime -to $toTime -performance -sort $sort -limit $limit -offset $offset -hosts:$hosts -vmdks:$vmdks -datasources:$datasources -storageResources:$storageResources -annotations:$annotations -Server $Server
            }
        }
    }
}

<#
    .SYNOPSIS
    Retrieve total count of datastores.
    .DESCRIPTION
    Retrieve total count of datastores.
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciDatastoreCount {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                   Position=0,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $Uri = $Server.BaseUri + "/rest/v1/assets/dataStores/count"
      
        try {
            $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
        }
        catch {
            $ResponseBody = ParseExceptionBody $_.Exception.Response
            Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
        }
 
        if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
            $Result = ParseJsonString($Result.Trim())
        }
           
        Write-Output $Result.value
    }
}

<#
    .SYNOPSIS
    Retrieve one datastore
    .DESCRIPTION
    Retrieve one datastore
    .PARAMETER id
    Id of datastore to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER performance
    Return related Performance
    .PARAMETER hosts
    Return list of related Hosts
    .PARAMETER vmdks
    Return list of related Vmdks
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER performancehistory
    Return related Performance History
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciDatastore {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of datastore to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Hosts")][Switch]$hosts,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Vmdks")][Switch]$vmdks,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=11,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/dataStores/$id"
 
            $switchparameters=@("performance","hosts","vmdks","datasources","storageResources","annotations","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            $Datastore = ParseDatastores($Result)
            Write-Output $Datastore
        }
    }
}

# TODO: Implement / Test

<#
    .SYNOPSIS
    Delete annotations from object
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>

[
{
  "definition":{"id":"5001"}
},
{
  "definition":{"id":"5002"}
}
]
</pre>
                     
    .PARAMETER id
    Id of object to delete
    .PARAMETER definition
    Return related Definition
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Remove-OciAnnotationsByDatastore {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of datastore to delete annotations from",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of annotation to delete",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$annotationId,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=11,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $CurrentOciServer.BaseUri + "/rest/v1/assets/dataStores/$id/annotations"
           
            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ConvertTo-Json @($applicationId | % { @{id=$_} }) -Compress
                Write-Verbose "Body: "
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers -Body "" -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
       
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve annotations for object
    .DESCRIPTION
     
    .PARAMETER id
    Id of object to retrieve
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=definition)
    .PARAMETER definition
    Return related Definition
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciAnnotationsByDatastore {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=definition)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/dataStores/$id/annotations"
 
            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($expand) {
                $Uri += "?$($Separator)expand=$expand"
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
            
            $Annotations = ParseAnnotations($Result)
            
            Write-Output $Annotations
        }
    }
}

<#
    .SYNOPSIS
    Update annotations for object
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>

[
  {
    "rawValue": "Bronze",
    "definition": {
      "id": "4992",
    }
  }
]
</pre>
             
    .PARAMETER id
    Id of object to update
    .PARAMETER definition
    Return related Definition
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Update-OciAnnotationsByDatastore {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$True,
                    Position=1,
                    HelpMessage="Annotation ID")][String]$annotationId,
        [parameter(Mandatory=$True,
                    Position=2,
                    HelpMessage="Annotation value")][String]$value,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=4,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/dataStores/$id/annotations"

            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($expand) {
                $Uri += "$($Separator)expand=$expand"
            }
 
            try {
                $Body = ConvertTo-Json @(@{rawValue=$value;definition=@{id=$annotationId}}) -Compress -Depth 3
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PUT -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PUT to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve datasources of a datastore.
    .DESCRIPTION
     
    .PARAMETER id
    Id of datastore to retrieve datasources for.
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER acquisitionUnit
    Return related Acquisition unit
    .PARAMETER note
    Return related Note
    .PARAMETER changes
    Return list of related Changes
    .PARAMETER packages
    Return list of related Packages
    .PARAMETER activePatch
    Return related Active patch
    .PARAMETER events
    Return list of related Events
    .PARAMETER devices
    Return list of related Devices
    .PARAMETER config
    Return related Config
#>

function Global:Get-OciDatasourcesByDataStore {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of datastore to retrieve datasources for.",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Acquisition unit")][Switch]$acquisitionUnit,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Note")][Switch]$note,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Changes")][Switch]$changes,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Packages")][Switch]$packages,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return related Active patch")][Switch]$activePatch,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Events")][Switch]$events,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Devices")][Switch]$devices,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Config")][Switch]$config,
        [parameter(Mandatory=$False,
                   Position=12,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/dataStores/$id/datasources"
 
            $switchparameters=@("acquisitionUnit","note","changes","packages","activePatch","events","devices","config")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
            
            $Datasources = ParseDatasources($Result)
            
            Write-Output $Datasources
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all hosts mapped to a datastore.
    .DESCRIPTION
     
    .PARAMETER id
    Id of the datastore to retrieve the hosts
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER performance
    Return related Performance
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER fileSystems
    Return list of related File systems
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER virtualMachines
    Return list of related Virtual machines
    .PARAMETER dataCenter
    Return related Data center
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER clusterHosts
    Return list of related Cluster hosts
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciHostsByDatastore {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of the datastore to retrieve the hosts",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related File systems")][Switch]$fileSystems,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Virtual machines")][Switch]$virtualMachines,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return related Data center")][Switch]$dataCenter,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return list of related Cluster hosts")][Switch]$clusterHosts,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=14,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=12,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/dataStores/$id/hosts"
 
            $switchparameters=@("performance","ports","storageResources","fileSystems","applications","virtualMachines","dataCenter","annotations","clusterHosts","datasources","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            $Hosts = ParseHosts($Result)
          
            Write-Output $Hosts
        }
    }
}

<#
    .SYNOPSIS
    Retrieve one datastore performance
    .DESCRIPTION
     
    .PARAMETER id
    Id of datastore to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER history
    Return list of related History
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciDatastorePerformance {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of datastore to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related History")][Switch]$history,
        [parameter(Mandatory=$False,
                   Position=5,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/dataStores/$id/performance"
 
            $switchparameters=@("history")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            $Performance = ParsePerformance($Result)
           
            Write-Output $Performance
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all storage resources mapped to a datastore.
    .DESCRIPTION
     
    .PARAMETER id
    Id of the datastore to retrieve the storage resources for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER performance
    Return related Performance
    .PARAMETER dataStores
    Return list of related Datastores
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER performancehistory
    Return related Performance History
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciStorageResourcesByDatastore {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of the datastore to retrieve the storage resources for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Datastores")][Switch]$dataStores,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=11,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/dataStores/$id/storageResources"
 
            $switchparameters=@("storage","performance","dataStores","computeResources","applications","storagePools","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
       
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all Vmdks belonging to a datastore.
    .DESCRIPTION
     
    .PARAMETER id
    Id of the datastore to retrieve the Vmdks
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER performance
    Return related Performance
    .PARAMETER dataStore
    Return related Datastore
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER virtualMachine
    Return related Virtual machine
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciVmdksByDatastore {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of the datastore to retrieve the Vmdks",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Datastore")][Switch]$dataStore,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return related Virtual machine")][Switch]$virtualMachine,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=5,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/dataStores/$id/vmdks"

            $switchparameters=@("performance","dataStore","storageResources","virtualMachine","annotations","datasources","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            $Vmdks = ParseVmdks($Result)
           
            Write-Output $Vmdks
        }
    }
}

<#
    .SYNOPSIS
    Retrieve one storage pool disk
    .DESCRIPTION
     
    .PARAMETER id
    Id of storage pool disk to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER performance
    Return related Performance
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER backendVolumes
    Return list of related Backend volumes
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER performancehistory
    Return related Performance History
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciDisk {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of storage pool disk to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Backend volumes")][Switch]$backendVolumes,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=12,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/disks/$id"
 
            $switchparameters=@("storage","storagePools","performance","storageResources","backendVolumes","annotations","datasources","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Delete annotations from object
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>

[
{
  "definition":{"id":"5001"}
},
{
  "definition":{"id":"5002"}
}
]
</pre>
                     
    .PARAMETER id
    Id of object to delete
    .PARAMETER definition
    Return related Definition
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Remove-OciAnnotationsByDisk {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to delete",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=5,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/disks/$id/annotations"

            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve annotations for object
    .DESCRIPTION
     
    .PARAMETER id
    Id of object to retrieve
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=definition)
    .PARAMETER definition
    Return related Definition
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciAnnotationsByDisk {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=definition)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/disks/$id/annotations"
 
            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Update annotations for object
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>

[
  {
    "rawValue": "Bronze",
    "definition": {
      "id": "4992",
    }
  }
]
</pre>
             
    .PARAMETER id
    Id of object to update
    .PARAMETER definition
    Return related Definition
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Update-OciAnnotationsByDisk {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=5,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/disks/$id/annotations"
 
            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PUT -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PUT to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve backend volumes of a virtual disk.
    .DESCRIPTION
     
    .PARAMETER id
    Id of the virtual disk to retrieve backend volumes for.
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER performance
    Return related Performance
    .PARAMETER dataStores
    Return list of related Datastores
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER virtualStoragePools
    Return list of related Virtual storage pools
    .PARAMETER virtualizer
    Return related Virtualizer
    .PARAMETER internalVolume
    Return related Internal volume
    .PARAMETER autoTierPolicy
    Return related Auto tier policy
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER storageNodes
    Return list of related Storage nodes
    .PARAMETER replicaSources
    Return list of related Replica sources
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER qtree
    Return related Qtree
    .PARAMETER performancehistory
    Return related Performance History
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciBackendVolumesByDisk {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of the virtual disk to retrieve backend volumes for.",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Datastores")][Switch]$dataStores,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Virtual storage pools")][Switch]$virtualStoragePools,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Virtualizer")][Switch]$virtualizer,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return related Internal volume")][Switch]$internalVolume,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return related Auto tier policy")][Switch]$autoTierPolicy,
        [parameter(Mandatory=$False,
                    Position=14,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=15,
                    HelpMessage="Return list of related Storage nodes")][Switch]$storageNodes,
        [parameter(Mandatory=$False,
                    Position=16,
                    HelpMessage="Return list of related Replica sources")][Switch]$replicaSources,
        [parameter(Mandatory=$False,
                    Position=17,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=18,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=19,
                    HelpMessage="Return related Qtree")][Switch]$qtree,
        [parameter(Mandatory=$False,
                    Position=20,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=21,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/disks/$id/backendVolumes"
 
            $switchparameters=@("storage","performance","dataStores","computeResources","applications","storagePools","virtualStoragePools","virtualizer","internalVolume","autoTierPolicy","ports","storageNodes","replicaSources","datasources","annotations","qtree","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve datasources of a disk.
    .DESCRIPTION
     
    .PARAMETER id
    Id of disk to retrieve datasources for.
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER acquisitionUnit
    Return related Acquisition unit
    .PARAMETER note
    Return related Note
    .PARAMETER changes
    Return list of related Changes
    .PARAMETER packages
    Return list of related Packages
    .PARAMETER activePatch
    Return related Active patch
    .PARAMETER events
    Return list of related Events
    .PARAMETER devices
    Return list of related Devices
    .PARAMETER config
    Return related Config
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciDatasourcesByDisk {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of disk to retrieve datasources for.",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Acquisition unit")][Switch]$acquisitionUnit,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Note")][Switch]$note,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Changes")][Switch]$changes,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Packages")][Switch]$packages,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return related Active patch")][Switch]$activePatch,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Events")][Switch]$events,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Devices")][Switch]$devices,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Config")][Switch]$config,
        [parameter(Mandatory=$False,
                   Position=12,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/disks/$id/datasources"
 
            $switchparameters=@("acquisitionUnit","note","changes","packages","activePatch","events","devices","config")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            $Datasources = ParseDatasources($Result)

            Write-Output $Datasources
        }
    }
}

<#
    .SYNOPSIS
    Retrieve one disk performance
    .DESCRIPTION
     
    .PARAMETER id
    Id of disk to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER history
    Return list of related History
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciDiskPerformance {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of disk to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related History")][Switch]$history,
        [parameter(Mandatory=$False,
                   Position=5,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/disks/$id/performance"

            $switchparameters=@("history")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            $Performance = ParsePerformance($Result)

            Write-Output $Performance
        }
    }
}

<#
    .SYNOPSIS
    Retrieve storage pools for disk
    .DESCRIPTION
     
    .PARAMETER id
    Id of disk to retrieve storage pools for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER performance
    Return related Performance
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER internalVolumes
    Return list of related Internal volumes
    .PARAMETER volumes
    Return list of related Volumes
    .PARAMETER disks
    Return list of related Disks
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER storageNodes
    Return list of related Storage nodes
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER performancehistory
    Return related Performance History
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciStoragePoolsByDisk {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of disk to retrieve storage pools for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Internal volumes")][Switch]$internalVolumes,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Volumes")][Switch]$volumes,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Disks")][Switch]$disks,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return list of related Storage nodes")][Switch]$storageNodes,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=5,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/disks/$id/storagePools"
 
            $switchparameters=@("storage","performance","storageResources","internalVolumes","volumes","disks","datasources","storageNodes","annotations","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve storage resources for disk
    .DESCRIPTION
     
    .PARAMETER id
    Id of disk to retrieve resources for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER performance
    Return related Performance
    .PARAMETER dataStores
    Return list of related Datastores
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER performancehistory
    Return related Performance History
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciStorageResourcesByDisk {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of disk to retrieve resources for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Datastores")][Switch]$dataStores,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=11,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/disks/$id/storageResources"
 
            $switchparameters=@("storage","performance","dataStores","computeResources","applications","storagePools","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
       
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all fabrics
    .DESCRIPTION
     
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER limit
    Number of fabrics per page.
    .PARAMETER offset
    Offset to be used with limit
    .PARAMETER switches
    Return list of related Switches
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciFabrics {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                    Position=0,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Number of fabrics per page.")][Long]$limit,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Offset to be used with limit")][Long]$offset,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Switches")][Switch]$switches,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                   Position=5,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/fabrics"
           
            $switchparameters=@("switches","datasources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve total count of fabrics.
    .DESCRIPTION
     
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciFabricCount {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                   Position=0,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $Uri = $Server.BaseUri + "/rest/v1/assets/fabrics/count"
 
        try {
            $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
        }
        catch {
            $ResponseBody = ParseExceptionBody $_.Exception.Response
            Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
        }
 
        if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
            $Result = ParseJsonString($Result.Trim())
        }
       
        Write-Output $Result
    }
}

<#
    .SYNOPSIS
    Retrieve one fabric
    .DESCRIPTION
     
    .PARAMETER id
    Id of fabric to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER switches
    Return list of related Switches
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciFabric {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of fabric to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related Switches")][Switch]$switches,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                   Position=6,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/fabrics/$id"

            $switchparameters=@("switches","datasources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve Datasources for one fabric
    .DESCRIPTION
     
    .PARAMETER id
    Id of fabric to retrieve datasources for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER acquisitionUnit
    Return related Acquisition unit
    .PARAMETER note
    Return related Note
    .PARAMETER changes
    Return list of related Changes
    .PARAMETER packages
    Return list of related Packages
    .PARAMETER activePatch
    Return related Active patch
    .PARAMETER events
    Return list of related Events
    .PARAMETER devices
    Return list of related Devices
    .PARAMETER config
    Return related Config
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciDatasourcesByFabric {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of fabric to retrieve datasources for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Acquisition unit")][Switch]$acquisitionUnit,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Note")][Switch]$note,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Changes")][Switch]$changes,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Packages")][Switch]$packages,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return related Active patch")][Switch]$activePatch,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Events")][Switch]$events,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Devices")][Switch]$devices,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Config")][Switch]$config,
        [parameter(Mandatory=$False,
                   Position=12,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/fabrics/$id/datasources"
 
            $switchparameters=@("acquisitionUnit","note","changes","packages","activePatch","events","devices","config")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve Ports for one fabric
    .DESCRIPTION
     
    .PARAMETER id
    Id of fabric to retrieve ports for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER limit
    Limit for number of ports in fabric to retrieve
    .PARAMETER sort
    sort will specify the field name on which sorting to be applied
    .PARAMETER offset
    Offset to be used with limit
    .PARAMETER device
    Return related Device Object
    .PARAMETER fabrics
    Return list of related Fabrics
    .PARAMETER performance
    Return related Performance
    .PARAMETER connectedPorts
    Return list of related Connected ports
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER performancehistory
    Return related Performance History
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciPortsByFabric {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of fabric to retrieve ports for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$True,
                    Position=4,
                    HelpMessage="Limit for number of ports in fabric to retrieve")][Long]$limit,
        [parameter(Mandatory=$True,
                    Position=5,
                    HelpMessage="sort will specify the field name on which sorting to be applied")][String]$sort,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Offset to be used with limit")][Long]$offset,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return related Device Object")][Switch]$device,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Fabrics")][Switch]$fabrics,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Connected ports")][Switch]$connectedPorts,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=14,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=15,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/fabrics/$id/ports"
           
            $switchparameters=@("device","fabrics","performance","connectedPorts","annotations","datasources","applications","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve total count of ports by fabric with performance.
    .DESCRIPTION
     
    .PARAMETER id
    Id of fabric to retrieve ports for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciPortsByFabricCount {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of fabric to retrieve ports for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/fabrics/$id/ports/count"

            $switchparameters=@("")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve switches for one fabric
    .DESCRIPTION
     
    .PARAMETER id
    Id of fabric to retrieve switches for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER fabric
    Return related Fabric
    .PARAMETER performance
    Return related Performance
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER performancehistory
    Return related Performance History
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciSwitchesByFabric {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of fabric to retrieve switches for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Fabric")][Switch]$fabric,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=11,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/fabrics/$id/switches"

            $switchparameters=@("fabric","performance","ports","annotations","datasources","applications","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve one file system
    .DESCRIPTION
     
    .PARAMETER id
    Id of file system to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER vmdks
    Return list of related Vmdks
    .PARAMETER computeResource
    Return related Compute resource
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciFilesystem {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of file system to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Vmdks")][Switch]$vmdks,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return related Compute resource")][Switch]$computeResource,
        [parameter(Mandatory=$False,
                   Position=7,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/fileSystems/$id"
 
            $switchparameters=@("storageResources","vmdks","computeResource")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
       
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve compute resource for a file system
    .DESCRIPTION
     
    .PARAMETER id
    Id of file system to retrieve the compute resource for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER performance
    Return related Performance
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER fileSystems
    Return list of related File systems
    .PARAMETER performancehistory
    Return related Performance History
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciComputeResourceByFileSystem {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of file system to retrieve the compute resource for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related File systems")][Switch]$fileSystems,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=9,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/fileSystems/$id/computeResource"

            $switchparameters=@("performance","ports","storageResources","fileSystems","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve storage resources for a file system
    .DESCRIPTION
     
    .PARAMETER id
    Id of file system to retrieve the storage resources for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER performance
    Return related Performance
    .PARAMETER dataStores
    Return list of related Datastores
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER performancehistory
    Return related Performance History
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciStorageResorcesByFileSystem {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of file system to retrieve the storage resources for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Datastores")][Switch]$dataStores,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=11,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/fileSystems/$id/storageResources"

            $switchparameters=@("storage","performance","dataStores","computeResources","applications","storagePools","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve VMDKs for a file system
    .DESCRIPTION
     
    .PARAMETER id
    Id of file system to retrieve the VMDKs for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER performance
    Return related Performance
    .PARAMETER dataStore
    Return related Datastore
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER virtualMachine
    Return related Virtual machine
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER performancehistory
    Return related Performance History
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciVmdksByFileSystem {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of file system to retrieve the VMDKs for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Datastore")][Switch]$dataStore,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return related Virtual machine")][Switch]$virtualMachine,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=11,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/fileSystems/$id/vmdks"

            $switchparameters=@("performance","dataStore","storageResources","virtualMachine","annotations","datasources","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
       
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all hosts
    .DESCRIPTION
     
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER sort
    Filter for sorting by metric/s
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER limit
    Number of hosts per page.
    .PARAMETER offset
    Offset to be used with limit
    .PARAMETER performance
    Return related Performance
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER fileSystems
    Return list of related File systems
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER virtualMachines
    Return list of related Virtual machines
    .PARAMETER dataCenter
    Return related Data center
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER clusterHosts
    Return list of related Cluster hosts
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER performancehistory
    Return related Performance History
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciHosts {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                    Position=0,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for sorting by metric/s")][String]$sort,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Number of hosts per page.")][Long]$limit,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Offset to be used with limit")][Long]$offset,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related File systems")][Switch]$fileSystems,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return list of related Virtual machines")][Switch]$virtualMachines,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return related Data center")][Switch]$dataCenter,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=14,
                    HelpMessage="Return list of related Cluster hosts")][Switch]$clusterHosts,
        [parameter(Mandatory=$False,
                    Position=15,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=16,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=17,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/hosts"
           
            $switchparameters=@("performance","ports","storageResources","fileSystems","applications","virtualMachines","dataCenter","annotations","clusterHosts","datasources","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            $Hosts = ParseHosts($Result)

            Write-Output $Hosts
        }
    }
}

<#
    .SYNOPSIS
    Retrieve total count of hosts.
    .DESCRIPTION
     
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciHostCount {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                   Position=5,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $Uri = $Server.BaseUri + "/rest/v1/assets/hosts/count"
 
        try {
            $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
        }
        catch {
            $ResponseBody = ParseExceptionBody $_.Exception.Response
            Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
        }
 
        if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
            $Result = ParseJsonString($Result.Trim())
        }

        Write-Output $Result
    }
}

<#
    .SYNOPSIS
    Retrieve one host
    .DESCRIPTION
     
    .PARAMETER id
    Id of host to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER performance
    Return related Performance
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER fileSystems
    Return list of related File systems
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER virtualMachines
    Return list of related Virtual machines
    .PARAMETER dataCenter
    Return related Data center
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER clusterHosts
    Return list of related Cluster hosts
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER performancehistory
    Return related Performance History
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciHost {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of host to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related File systems")][Switch]$fileSystems,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Virtual machines")][Switch]$virtualMachines,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return related Data center")][Switch]$dataCenter,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return list of related Cluster hosts")][Switch]$clusterHosts,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=14,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=5,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/hosts/$id"
 
            $switchparameters=@("performance","ports","storageResources","fileSystems","applications","virtualMachines","dataCenter","annotations","clusterHosts","datasources","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
            
            $Host = ParseHosts($Result)
            
            Write-Output $Host
        }
    }
}

<#
    .SYNOPSIS
    Delete annotations from object
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>

[
{
  "definition":{"id":"5001"}
},
{
  "definition":{"id":"5002"}
}
]
</pre>
                     
    .PARAMETER id
    Id of object to delete
    .PARAMETER definition
    Return related Definition
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Remove-OciAnnotationsByHosts {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to delete",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=5,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/hosts/$id/annotations"
           
            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve annotations for object
    .DESCRIPTION
     
    .PARAMETER id
    Id of object to retrieve
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=definition)
    .PARAMETER definition
    Return related Definition
    .PARAMETER server
    OCI Server to connect to
#>

function Global:Get-OciAnnotationsByHosts {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=definition)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $($Server.BaseUri) + "/rest/v1/assets/hosts/$id/annotations"

            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Update annotations for object
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>

[
  {
    "rawValue": "Bronze",
    "definition": {
      "id": "4992",
    }
  }
]
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER definition
        Return related Definition
#>

function Global:Update-OciAnnotationsByHost {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=2,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/hosts/$id/annotations"
 
            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PUT -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PUT to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Bulk un-assign applications from asset
    .DESCRIPTION
    Request body should contain a list of valid application ids, example: <br/>

<pre>
[
    {
        "id":"12345"
    },
    {
        "id":"67890"
    }
]
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER computeResources
        Return list of related Compute resources
        .PARAMETER storageResources
        Return list of related Storage resources
#>

function Global:Bulk-OciUnAssignApplicationsFromAsset {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/hosts/$id/applications"
 
            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve the applications of object
    .DESCRIPTION
     
    .PARAMETER id
    Id of object to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER storageResources
    Return list of related Storage resources
#>

function Global:Get-OciByTypeAndId {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=6,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/hosts/$id/applications"
 
            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Bulk assign applications to asset
    .DESCRIPTION
    Request body should contain a list of valid application ids, example: <br/>

<pre>
[
    {
        "id":"12345"
    },
    {
        "id":"67890"
    }
]
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER computeResources
        Return list of related Compute resources
        .PARAMETER storageResources
        Return list of related Storage resources
#>

function Global:Bulk-OciAssignApplicationsToAsset {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/hosts/$id/applications"

            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PATCH -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PATCH to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Add applications for object
    .DESCRIPTION
    Request body should contain only one valid application id, example: <br/>

<pre>
{
    "id":"12345"
}
</pre>
             
    .PARAMETER id
    Id of object to update
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER storageResources
    Return list of related Storage resources
#>

function Global:Update-OciByTypeAndId {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/hosts/$id/applications"
 
            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "POST to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Delete application from object
    .DESCRIPTION
     
    .PARAMETER id
    Id of object to delete application from
    .PARAMETER appId
    Id of application to delete from object
        .PARAMETER computeResources
        Return list of related Compute resources
        .PARAMETER storageResources
        Return list of related Storage resources
#>

function Global:Remove-OciByTypeAndId {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to delete application from",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$True,
                    Position=1,
                    HelpMessage="Id of application to delete from object")][Long]$appId,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=4,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $($Server.BaseUri) + "/rest/v1/assets/hosts/$id$/applications/$appId"

            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve the hosts from same cluster of host
    .DESCRIPTION
     
    .PARAMETER id
    Id of host to retrieve cluster hosts for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER performance
    Return related Performance
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER fileSystems
    Return list of related File systems
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER virtualMachines
    Return list of related Virtual machines
    .PARAMETER dataCenter
    Return related Data center
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER clusterHosts
    Return list of related Cluster hosts
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciClusterHostsByHost {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of host to retrieve cluster hosts for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related File systems")][Switch]$fileSystems,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Virtual machines")][Switch]$virtualMachines,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return related Data center")][Switch]$dataCenter,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return list of related Cluster hosts")][Switch]$clusterHosts,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=14,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=15,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/hosts/$id/clusterHosts"

            $switchparameters=@("performance","ports","storageResources","fileSystems","applications","virtualMachines","dataCenter","annotations","clusterHosts","datasources","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve the data center of host
    .DESCRIPTION
     
    .PARAMETER id
    Id of host to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
#>

function Global:Get-OciDataCenterByHost {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of host to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                   Position=4,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/hosts/$id/dataCenter"
           
            $switchparameters=@("")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve datasources of a host.
    .DESCRIPTION
     
    .PARAMETER id
    Id of host to retrieve datasources for.
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER acquisitionUnit
    Return related Acquisition unit
    .PARAMETER note
    Return related Note
    .PARAMETER changes
    Return list of related Changes
    .PARAMETER packages
    Return list of related Packages
    .PARAMETER activePatch
    Return related Active patch
    .PARAMETER events
    Return list of related Events
    .PARAMETER devices
    Return list of related Devices
    .PARAMETER config
    Return related Config
#>

function Global:Get-OciDatasourcesByHost {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of host to retrieve datasources for.",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Acquisition unit")][Switch]$acquisitionUnit,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Note")][Switch]$note,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Changes")][Switch]$changes,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Packages")][Switch]$packages,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return related Active patch")][Switch]$activePatch,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Events")][Switch]$events,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Devices")][Switch]$devices,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Config")][Switch]$config,
        [parameter(Mandatory=$False,
                   Position=12,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/hosts/$id/datasources"
           
            $switchparameters=@("acquisitionUnit","note","changes","packages","activePatch","events","devices","config")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve the file systems of host
    .DESCRIPTION
     
    .PARAMETER id
    Id of host to retrieve file systems for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER vmdks
    Return list of related Vmdks
    .PARAMETER computeResource
    Return related Compute resource
#>

function Global:Get-OciFileSystemsByHost {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of host to retrieve file systems for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Vmdks")][Switch]$vmdks,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return related Compute resource")][Switch]$computeResource,
        [parameter(Mandatory=$False,
                   Position=7,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/hosts/$id/fileSystems"

            $switchparameters=@("storageResources","vmdks","computeResource")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve one host performance
    .DESCRIPTION
     
    .PARAMETER id
    Id of host to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER history
    Return list of related History
#>

function Global:Get-OciHostPerformance {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of host to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related History")][Switch]$history,
        [parameter(Mandatory=$False,
                   Position=5,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/hosts/$id/performance"
           
            $switchparameters=@("history")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve the ports of host
    .DESCRIPTION
     
    .PARAMETER id
    Id of host to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER device
    Return related Device Object
    .PARAMETER fabrics
    Return list of related Fabrics
    .PARAMETER performance
    Return related Performance
    .PARAMETER connectedPorts
    Return list of related Connected ports
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciPortsByHost {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of host to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Device Object")][Switch]$device,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Fabrics")][Switch]$fabrics,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Connected ports")][Switch]$connectedPorts,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=12,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/hosts/$id/ports"
 
            $switchparameters=@("device","fabrics","performance","connectedPorts","annotations","datasources","applications","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all storage resources by host
    .DESCRIPTION
     
    .PARAMETER id
    Id of host to retrieve storage resources for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER performance
    Return related Performance
    .PARAMETER dataStores
    Return list of related Datastores
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciStorageResourcesByHost {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of host to retrieve storage resources for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Datastores")][Switch]$dataStores,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=11,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/hosts/$id/storageResources"
           
            $switchparameters=@("storage","performance","dataStores","computeResources","applications","storagePools","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve the virtual machines of host
    .DESCRIPTION
     
    .PARAMETER id
    Id of host to retrieve virtual machines for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER performance
    Return related Performance
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER fileSystems
    Return list of related File systems
    .PARAMETER dataStore
    Return related Datastore
    .PARAMETER host
    Return related Host
    .PARAMETER vmdks
    Return list of related Vmdks
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciVirtualMachinesByHost {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of host to retrieve virtual machines for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related File systems")][Switch]$fileSystems,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return related Datastore")][Switch]$dataStore,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return related Host")][Switch]$host,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Vmdks")][Switch]$vmdks,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=14,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=15,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/hosts/$id/virtualMachines"

            $switchparameters=@("performance","ports","storageResources","fileSystems","dataStore","host","vmdks","applications","annotations","datasources","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve internal volume
    .DESCRIPTION
     
    .PARAMETER id
    Id of internal volume to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER performance
    Return related Performance
    .PARAMETER dataStores
    Return list of related Datastores
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER storagePool
    Return related Storage pool
    .PARAMETER volumes
    Return list of related Volumes
    .PARAMETER storageNodes
    Return list of related Storage nodes
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER replicaSources
    Return list of related Replica sources
    .PARAMETER qtrees
    Return list of related Qtrees
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciInternalVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of internal volume to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Datastores")][Switch]$dataStores,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return related Storage pool")][Switch]$storagePool,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Volumes")][Switch]$volumes,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return list of related Storage nodes")][Switch]$storageNodes,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=14,
                    HelpMessage="Return list of related Replica sources")][Switch]$replicaSources,
        [parameter(Mandatory=$False,
                    Position=15,
                    HelpMessage="Return list of related Qtrees")][Switch]$qtrees,
        [parameter(Mandatory=$False,
                    Position=16,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=5,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/internalVolumes/$id"

            $switchparameters=@("storage","performance","dataStores","computeResources","applications","storagePool","volumes","storageNodes","annotations","datasources","replicaSources","qtrees","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Delete annotations from object
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>

[
{
  "definition":{"id":"5001"}
},
{
  "definition":{"id":"5002"}
}
]
</pre>
                     
    .PARAMETER id
    Id of object to delete
        .PARAMETER definition
        Return related Definition
#>

function Global:Remove-OciAnnotationsByInternalVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to delete",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=5,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/internalVolumes/$id/annotations"

            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve annotations for object
    .DESCRIPTION
     
    .PARAMETER id
    Id of object to retrieve
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=definition)
        .PARAMETER definition
        Return related Definition
#>

function Global:Get-OciAnnotationsByInternalVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=definition)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/internalVolumes/$id/annotations"
 
            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Update annotations for object
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>

[
  {
    "rawValue": "Bronze",
    "definition": {
      "id": "4992",
    }
  }
]
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER definition
        Return related Definition
#>

function Global:Update-OciAnnotationsByInternalVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=2,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/internalVolumes/$id/annotations"

            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PUT -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PUT to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Bulk un-assign applications from internal volume
    .DESCRIPTION
    Bulk un-assign applications from internal volume
    .PARAMETER id
    Id of internal volume to update
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER storageResources
    Return list of related Storage resources
#>

function Global:Remove-OciApplicationsFromInternalVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$True,
                    Position=1,
                    HelpMessage="List of application IDs",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][String[]]$applicationId,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=4,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/internalVolumes/$id/applications"

            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($expand) {
                $Uri += "?$($Separator)expand=$expand"
            }
 
            try {
                $Body = ConvertTo-Json @($applicationId | % { @{id=$_} }) -Compress
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
       
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve the applications of object
    .DESCRIPTION
     
    .PARAMETER id
    Id of object to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER storageResources
    Return list of related Storage resources
#>

function Global:Get-OciApplicationsByInternalVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=6,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/internalVolumes/$id/applications"

            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Bulk assign applications to internal volume
    .DESCRIPTION
    Bulk assign applications to internal volume
    .PARAMETER id
    Id of object to update
    .PARAMETER applicationId
    List of application IDs
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER storageResources
    Return list of related Storage resources
#>

function Global:Add-OciApplicationsToInternalVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of internal volume",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$True,
                    Position=1,
                    HelpMessage="List of application IDs",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][String[]]$applicationId,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=4,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        $applicationId = @($applicationId)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/internalVolumes/$id/applications"
 
            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($expand) {
                $Uri += "?$($Separator)expand=$expand"
            }
 
            try {
                $Body = ConvertTo-Json @($applicationId | % { @{id=$_} }) -Compress
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PATCH -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PATCH to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Add applications for object
    .DESCRIPTION
    Request body should contain only one valid application id, example: <br/>

<pre>
{
    "id":"12345"
}
</pre>
             
    .PARAMETER id
    Id of object to update
    .PARAMETER applicationId
    Valid application id which should be associated
        .PARAMETER computeResources
        Return list of related Compute resources
        .PARAMETER storageResources
        Return list of related Storage resources
#>

function Global:Update-OciApplicationsByInternalVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$True,
                    Position=1,
                    HelpMessage="Valid application id which should be associated")][String]$applicationId,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=5,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/internalVolumes/$id/applications"
 
            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = "{ `"id`": `"$applicationId`" }"
                    Write-Verbose "Body: $Body"
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "POST to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Delete application from internal volume
    .DESCRIPTION
    Delete application from internal volume
    .PARAMETER id
    Id of object to delete application from
    .PARAMETER appId
    Id of application to delete from object
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER storageResources
    Return list of related Storage resources
#>

function Global:Remove-OciApplicationsByInternalVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of internal volume to delete application from",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$True,
                    Position=1,
                    HelpMessage="Id of application to delete from object")][Long]$appId,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=4,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/internalVolumes/$id/applications/$appId"
 
            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($expand) {
                $Uri += "?$($Separator)expand=$expand"
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all compute resources for an internal volume
    .DESCRIPTION
     
    .PARAMETER id
    Id of internal volume to retrieve compute resources for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER performance
    Return related Performance
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER fileSystems
    Return list of related File systems
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciComputeResourcesByInternalVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of internal volume to retrieve compute resources for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related File systems")][Switch]$fileSystems,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=9,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/internalVolumes/$id/computeResources"

            $switchparameters=@("performance","ports","storageResources","fileSystems","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all data stores for an internal volume
    .DESCRIPTION
     
    .PARAMETER id
    Id of internal volume to retrieve data stores for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER performance
    Return related Performance
    .PARAMETER hosts
    Return list of related Hosts
    .PARAMETER vmdks
    Return list of related Vmdks
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciDataStoresByInternalVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of internal volume to retrieve data stores for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Hosts")][Switch]$hosts,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Vmdks")][Switch]$vmdks,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=11,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/internalVolumes/$id/dataStores"
 
            $switchparameters=@("performance","hosts","vmdks","datasources","storageResources","annotations","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve the datasources for an internal volume
    .DESCRIPTION
     
    .PARAMETER id
    Id of internal volume to retrieve datasource for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER acquisitionUnit
    Return related Acquisition unit
    .PARAMETER note
    Return related Note
    .PARAMETER changes
    Return list of related Changes
    .PARAMETER packages
    Return list of related Packages
    .PARAMETER activePatch
    Return related Active patch
    .PARAMETER events
    Return list of related Events
    .PARAMETER devices
    Return list of related Devices
    .PARAMETER config
    Return related Config
#>

function Global:Get-OciDatasourcesByInternalVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of internal volume to retrieve datasource for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Acquisition unit")][Switch]$acquisitionUnit,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Note")][Switch]$note,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Changes")][Switch]$changes,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Packages")][Switch]$packages,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return related Active patch")][Switch]$activePatch,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Events")][Switch]$events,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Devices")][Switch]$devices,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Config")][Switch]$config,
        [parameter(Mandatory=$False,
                   Position=12,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/internalVolumes/$id/datasources"
 
            $switchparameters=@("acquisitionUnit","note","changes","packages","activePatch","events","devices","config")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve internal volume performance
    .DESCRIPTION
     
    .PARAMETER id
    Id of internal volume to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
        .PARAMETER history
        Return list of related History
#>

function Global:Get-OciInternalVolumePerformance {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of internal volume to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related History")][Switch]$history,
        [parameter(Mandatory=$False,
                   Position=5,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/internalVolumes/$id/performance"
 
            $switchparameters=@("history")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve qtrees for one internal volume
    .DESCRIPTION
     
    .PARAMETER id
    Id of internal volume to retrieve storage qtrees for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER internalVolume
    Return related Internal volume
    .PARAMETER shares
    Return list of related Shares
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER volumes
    Return list of related Volumes
#>

function Global:Get-OciQtreesByInternalVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of internal volume to retrieve storage qtrees for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Internal volume")][Switch]$internalVolume,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Shares")][Switch]$shares,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Volumes")][Switch]$volumes,
        [parameter(Mandatory=$False,
                   Position=10,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/internalVolumes/$id/qtrees"

            $switchparameters=@("storage","internalVolume","shares","annotations","applications","volumes")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all replica source internal volumes for an internal volume
    .DESCRIPTION
     
    .PARAMETER id
    Id of internal volume to retrieve replica source internal volumes for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER performance
    Return related Performance
    .PARAMETER dataStores
    Return list of related Datastores
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER storagePool
    Return related Storage pool
    .PARAMETER volumes
    Return list of related Volumes
    .PARAMETER storageNodes
    Return list of related Storage nodes
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER replicaSources
    Return list of related Replica sources
    .PARAMETER qtrees
    Return list of related Qtrees
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciSourceInternalVolumesByInternalVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of internal volume to retrieve replica source internal volumes for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Datastores")][Switch]$dataStores,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return related Storage pool")][Switch]$storagePool,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Volumes")][Switch]$volumes,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return list of related Storage nodes")][Switch]$storageNodes,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=14,
                    HelpMessage="Return list of related Replica sources")][Switch]$replicaSources,
        [parameter(Mandatory=$False,
                    Position=15,
                    HelpMessage="Return list of related Qtrees")][Switch]$qtrees,
        [parameter(Mandatory=$False,
                    Position=16,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=17,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/internalVolumes/$id/replicaSources"

            $switchparameters=@("storage","performance","dataStores","computeResources","applications","storagePool","volumes","storageNodes","annotations","datasources","replicaSources","qtrees","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all storage nodes for an internal volume
    .DESCRIPTION
     
    .PARAMETER id
    Id of internal volume to retrieve storage nodes for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER partner
    Return related HA partner
    .PARAMETER performance
    Return related Performance
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciStorageNodesByInternalVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of internal volume to retrieve storage nodes for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related HA partner")][Switch]$partner,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=12,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/internalVolumes/$id/storageNodes"

            $switchparameters=@("storage","partner","performance","datasources","storagePools","ports","annotations","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all volumes for an internal volume
    .DESCRIPTION
     
    .PARAMETER id
    Id of internal volume to retrieve volumes for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER performance
    Return related Performance
    .PARAMETER dataStores
    Return list of related Datastores
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER virtualStoragePools
    Return list of related Virtual storage pools
    .PARAMETER virtualizer
    Return related Virtualizer
    .PARAMETER internalVolume
    Return related Internal volume
    .PARAMETER autoTierPolicy
    Return related Auto tier policy
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER storageNodes
    Return list of related Storage nodes
    .PARAMETER replicaSources
    Return list of related Replica sources
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER qtree
    Return related Qtree
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciVolumesByInternalVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of internal volume to retrieve volumes for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Datastores")][Switch]$dataStores,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Virtual storage pools")][Switch]$virtualStoragePools,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Virtualizer")][Switch]$virtualizer,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return related Internal volume")][Switch]$internalVolume,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return related Auto tier policy")][Switch]$autoTierPolicy,
        [parameter(Mandatory=$False,
                    Position=14,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=15,
                    HelpMessage="Return list of related Storage nodes")][Switch]$storageNodes,
        [parameter(Mandatory=$False,
                    Position=16,
                    HelpMessage="Return list of related Replica sources")][Switch]$replicaSources,
        [parameter(Mandatory=$False,
                    Position=17,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=18,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=19,
                    HelpMessage="Return related Qtree")][Switch]$qtree,
        [parameter(Mandatory=$False,
                    Position=20,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=4,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/internalVolumes/$id/volumes"
 
            $switchparameters=@("storage","performance","dataStores","computeResources","applications","storagePools","virtualStoragePools","virtualizer","internalVolume","autoTierPolicy","ports","storageNodes","replicaSources","datasources","annotations","qtree","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve one port
    .DESCRIPTION
     
    .PARAMETER id
    Id of port to retrieve
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER device
    Return related Device Object
    .PARAMETER fabrics
    Return list of related Fabrics
    .PARAMETER performance
    Return related Performance
    .PARAMETER connectedPorts
    Return list of related Connected ports
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciPort {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of port to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Device Object")][Switch]$device,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Fabrics")][Switch]$fabrics,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Connected ports")][Switch]$connectedPorts,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=4,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/ports/$id"

            $switchparameters=@("device","fabrics","performance","connectedPorts","annotations","datasources","applications","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Delete annotations from object
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>

[
{
  "definition":{"id":"5001"}
},
{
  "definition":{"id":"5002"}
}
]
</pre>
                     
    .PARAMETER id
    Id of object to delete
        .PARAMETER definition
        Return related Definition
#>

function Global:Remove-OciAnnotationsByPort {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to delete",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=2,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/ports/$id/annotations"
 
            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
       
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve annotations for object
    .DESCRIPTION
     
    .PARAMETER id
    Id of object to retrieve
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=definition)
        .PARAMETER definition
        Return related Definition
#>

function Global:Get-OciAnnotationsByPort {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=definition)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/ports/$id/annotations"

            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Update annotations for object
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>

[
  {
    "rawValue": "Bronze",
    "definition": {
      "id": "4992",
    }
  }
]
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER definition
        Return related Definition
#>

function Global:Update-OciAnnotationsByPort {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=2,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/ports/$id/annotations"
           
            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: "
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PUT -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PUT to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Bulk un-assign applications from asset
    .DESCRIPTION
    Request body should contain a list of valid application ids, example: <br/>

<pre>
[
    {
        "id":"12345"
    },
    {
        "id":"67890"
    }
]
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER computeResources
        Return list of related Compute resources
        .PARAMETER storageResources
        Return list of related Storage resources
#>

function Global:Bulk-OciUnAssignApplicationsFromAsset {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/ports/$id/applications"
 
            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                Write-Verbose "Body: "
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve the applications of object
    .DESCRIPTION
     
    .PARAMETER id
    Id of object to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
        .PARAMETER computeResources
        Return list of related Compute resources
        .PARAMETER storageResources
        Return list of related Storage resources
#>

function Global:Get-OciByTypeAndId {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=6,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/ports/$id/applications"
 
            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Bulk assign applications to asset
    .DESCRIPTION
    Request body should contain a list of valid application ids, example: <br/>

<pre>
[
    {
        "id":"12345"
    },
    {
        "id":"67890"
    }
]
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER computeResources
        Return list of related Compute resources
        .PARAMETER storageResources
        Return list of related Storage resources
#>

function Global:Bulk-OciAssignApplicationsToAsset {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/ports/$id/applications"
 
            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PATCH -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PATCH to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Add applications for object
    .DESCRIPTION
    Request body should contain only one valid application id, example: <br/>

<pre>
{
    "id":"12345"
}
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER computeResources
        Return list of related Compute resources
        .PARAMETER storageResources
        Return list of related Storage resources
#>

function Global:Update-OciByTypeAndId {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=4,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/ports/$id/applications"

            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: "
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "POST to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve connected ports for one port
    .DESCRIPTION
     
    .PARAMETER id
    Id of port to retrieve connected port for
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER device
    Return related Device Object
    .PARAMETER fabrics
    Return list of related Fabrics
    .PARAMETER performance
    Return related Performance
    .PARAMETER connectedPorts
    Return list of related Connected ports
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciConnectedPortsByPort {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of port to retrieve connected port for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Device Object")][Switch]$device,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Fabrics")][Switch]$fabrics,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Connected ports")][Switch]$connectedPorts,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=12,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/ports/$id/connectedPorts"
  
            $switchparameters=@("device","fabrics","performance","connectedPorts","annotations","datasources","applications","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve datasources of a port.
    .DESCRIPTION
     
    .PARAMETER id
    Id of port to retrieve datasources for.
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER acquisitionUnit
    Return related Acquisition unit
    .PARAMETER note
    Return related Note
    .PARAMETER changes
    Return list of related Changes
    .PARAMETER packages
    Return list of related Packages
    .PARAMETER activePatch
    Return related Active patch
    .PARAMETER events
    Return list of related Events
    .PARAMETER devices
    Return list of related Devices
    .PARAMETER config
    Return related Config
#>

function Global:Get-OciDatasourcesByPort {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of port to retrieve datasources for.",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Acquisition unit")][Switch]$acquisitionUnit,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Note")][Switch]$note,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Changes")][Switch]$changes,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Packages")][Switch]$packages,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return related Active patch")][Switch]$activePatch,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Events")][Switch]$events,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Devices")][Switch]$devices,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Config")][Switch]$config,
        [parameter(Mandatory=$False,
                   Position=12,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/ports/$id/datasources"
 
            $switchparameters=@("acquisitionUnit","note","changes","packages","activePatch","events","devices","config")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve one device for port
    .DESCRIPTION
     
    .PARAMETER id
    Id of port to retrieve device
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
#>

function Global:Get-OciDeviceByPort {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of port to retrieve device",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                   Position=4,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/ports/$id/device"
 
            $switchparameters=@("")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
       
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve Fabric for port
    .DESCRIPTION
     
    .PARAMETER id
    Id of port to retrieve fabric
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER switches
    Return list of related Switches
    .PARAMETER datasources
    Return list of related Datasources
#>

function Global:Get-OciFabricsByPort {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of port to retrieve fabric",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related Switches")][Switch]$switches,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                   Position=6,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/ports/$id/fabrics"
 
            $switchparameters=@("switches","datasources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve one port performance
    .DESCRIPTION
     
    .PARAMETER id
    Id of port to retrieve
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER history
    Return list of related History
#>

function Global:Get-OciPortPerformance {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of port to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related History")][Switch]$history,
        [parameter(Mandatory=$False,
                   Position=4,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/ports/$id/performance"
 
            $switchparameters=@("history")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve one Qtree
    .DESCRIPTION
     
    .PARAMETER id
    Id of qtree to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER internalVolume
    Return related Internal volume
    .PARAMETER shares
    Return list of related Shares
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER volumes
    Return list of related Volumes
#>

function Global:Get-OciQtree {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of qtree to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Internal volume")][Switch]$internalVolume,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Shares")][Switch]$shares,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Volumes")][Switch]$volumes,
        [parameter(Mandatory=$False,
                   Position=10,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/qtrees/$id"

            $switchparameters=@("storage","internalVolume","shares","annotations","applications","volumes")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Delete annotations from object
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>

[
{
  "definition":{"id":"5001"}
},
{
  "definition":{"id":"5002"}
}
]
</pre>
                     
    .PARAMETER id
    Id of object to delete
        .PARAMETER definition
        Return related Definition
#>

function Global:Remove-OciByTypeAndId {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to delete",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=2,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/qtrees/$id/annotations"

            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve annotations for object
    .DESCRIPTION
     
    .PARAMETER id
    Id of object to retrieve
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=definition)
    .PARAMETER definition
    Return related Definition
#>

function Global:Get-OciByTypeAndId {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=definition)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/qtrees/$id/annotations"

            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
          
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Update annotations for object
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>

[
  {
    "rawValue": "Bronze",
    "definition": {
      "id": "4992",
    }
  }
]
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER definition
        Return related Definition
#>

function Global:Update-OciByTypeAndId {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=2,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/qtrees/$id/annotations"
 
            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PUT -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PUT to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Bulk un-assign applications from asset
    .DESCRIPTION
    Request body should contain a list of valid application ids, example: <br/>

<pre>
[
    {
        "id":"12345"
    },
    {
        "id":"67890"
    }
]
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER computeResources
        Return list of related Compute resources
        .PARAMETER storageResources
        Return list of related Storage resources
#>

function Global:Bulk-OciUnAssignApplicationsFromAsset {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/qtrees/$id/applications"

            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve the applications of object
    .DESCRIPTION
     
    .PARAMETER id
    Id of object to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER storageResources
    Return list of related Storage resources
#>

function Global:Get-OciByTypeAndId {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=6,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/qtrees/$id/applications"
 
           
            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Bulk assign applications to asset
    .DESCRIPTION
    Request body should contain a list of valid application ids, example: <br/>

<pre>
[
    {
        "id":"12345"
    },
    {
        "id":"67890"
    }
]
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER computeResources
        Return list of related Compute resources
        .PARAMETER storageResources
        Return list of related Storage resources
#>

function Global:Bulk-OciAssignApplicationsToAsset {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/qtrees/$id/applications"
 
            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PATCH -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PATCH to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Add applications for object
    .DESCRIPTION
    Request body should contain only one valid application id, example: <br/>

<pre>
{
    "id":"12345"
}
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER computeResources
        Return list of related Compute resources
        .PARAMETER storageResources
        Return list of related Storage resources
#>

function Global:Update-OciByTypeAndId {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/qtrees/$id/applications"
           
            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "POST to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Delete application from object
    .DESCRIPTION
     
    .PARAMETER id
    Id of object to delete application from
    .PARAMETER appId
    Id of application to delete from object
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER storageResources
    Return list of related Storage resources
#>

function Global:Remove-OciByTypeAndId {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to delete application from",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$True,
                    Position=1,
                    HelpMessage="Id of application to delete from object")][Long]$appId,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/qtrees/$id/applications/$appId"
 
            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve internal volume for given qtree
    .DESCRIPTION
     
    .PARAMETER id
    Id of qtree to retrieve internal volume for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER performance
    Return related Performance
    .PARAMETER dataStores
    Return list of related Datastores
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER storagePool
    Return related Storage pool
    .PARAMETER volumes
    Return list of related Volumes
    .PARAMETER storageNodes
    Return list of related Storage nodes
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER replicaSources
    Return list of related Replica sources
    .PARAMETER qtrees
    Return list of related Qtrees
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciInternalVolumeByQtree {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of qtree to retrieve internal volume for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Datastores")][Switch]$dataStores,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return related Storage pool")][Switch]$storagePool,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Volumes")][Switch]$volumes,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return list of related Storage nodes")][Switch]$storageNodes,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=14,
                    HelpMessage="Return list of related Replica sources")][Switch]$replicaSources,
        [parameter(Mandatory=$False,
                    Position=15,
                    HelpMessage="Return list of related Qtrees")][Switch]$qtrees,
        [parameter(Mandatory=$False,
                    Position=16,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=17,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/qtrees/$id/internalVolume"
 
            $switchparameters=@("storage","performance","dataStores","computeResources","applications","storagePool","volumes","storageNodes","annotations","datasources","replicaSources","qtrees","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve shares for one qtree
    .DESCRIPTION
     
    .PARAMETER id
    Id of qtree to retrieve shares for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER qtree
    Return related Qtree
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER applications
    Return list of related Applications
#>

function Global:Get-OciSharesByQtree {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of qtree to retrieve shares for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Qtree")][Switch]$qtree,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Applications")][Switch]$applications
    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/qtrees/$id/shares"

            $switchparameters=@("storage","qtree","annotations","applications")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve storage for given qtree
    .DESCRIPTION
     
    .PARAMETER id
    Id of qtree to retrieve storage for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storageNodes
    Return list of related Storage nodes
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER internalVolumes
    Return list of related Internal volumes
    .PARAMETER volumes
    Return list of related Volumes
    .PARAMETER qtrees
    Return list of related Qtrees
    .PARAMETER shares
    Return list of related Shares
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER disks
    Return list of related Disks
    .PARAMETER performance
    Return related Performance
    .PARAMETER protocols
    Return list of related Protocols
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciStorage {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of qtree to retrieve storage for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related Storage nodes")][Switch]$storageNodes,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Internal volumes")][Switch]$internalVolumes,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Volumes")][Switch]$volumes,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Qtrees")][Switch]$qtrees,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Shares")][Switch]$shares,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=14,
                    HelpMessage="Return list of related Disks")][Switch]$disks,
        [parameter(Mandatory=$False,
                    Position=15,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=16,
                    HelpMessage="Return list of related Protocols")][Switch]$protocols,
        [parameter(Mandatory=$False,
                    Position=17,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=18,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=19,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/qtrees/$id/storage"
 
            $switchparameters=@("storageNodes","storageResources","storagePools","internalVolumes","volumes","qtrees","shares","ports","datasources","annotations","disks","performance","protocols","applications","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve volumes for one qtree
    .DESCRIPTION
     
    .PARAMETER id
    Id of qtree to retrieve volumes for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER performance
    Return related Performance
    .PARAMETER dataStores
    Return list of related Datastores
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER virtualStoragePools
    Return list of related Virtual storage pools
    .PARAMETER virtualizer
    Return related Virtualizer
    .PARAMETER internalVolume
    Return related Internal volume
    .PARAMETER autoTierPolicy
    Return related Auto tier policy
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER storageNodes
    Return list of related Storage nodes
    .PARAMETER replicaSources
    Return list of related Replica sources
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER qtree
    Return related Qtree
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciVolumesByQtree {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of qtree to retrieve volumes for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Datastores")][Switch]$dataStores,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Virtual storage pools")][Switch]$virtualStoragePools,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Virtualizer")][Switch]$virtualizer,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return related Internal volume")][Switch]$internalVolume,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return related Auto tier policy")][Switch]$autoTierPolicy,
        [parameter(Mandatory=$False,
                    Position=14,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=15,
                    HelpMessage="Return list of related Storage nodes")][Switch]$storageNodes,
        [parameter(Mandatory=$False,
                    Position=16,
                    HelpMessage="Return list of related Replica sources")][Switch]$replicaSources,
        [parameter(Mandatory=$False,
                    Position=17,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=18,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=19,
                    HelpMessage="Return related Qtree")][Switch]$qtree,
        [parameter(Mandatory=$False,
                    Position=20,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=21,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/qtrees/$id/volumes"

            $switchparameters=@("storage","performance","dataStores","computeResources","applications","storagePools","virtualStoragePools","virtualizer","internalVolume","autoTierPolicy","ports","storageNodes","replicaSources","datasources","annotations","qtree","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve one Share
    .DESCRIPTION
     
    .PARAMETER id
    Id of share to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER qtree
    Return related Qtree
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER applications
    Return list of related Applications
#>

function Global:Get-OciShare {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of share to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Qtree")][Switch]$qtree,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                   Position=8,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/shares/$id"

            $switchparameters=@("storage","qtree","annotations","applications")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Delete annotations from object
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>

[
{
  "definition":{"id":"5001"}
},
{
  "definition":{"id":"5002"}
}
]
</pre>
                     
    .PARAMETER id
    Id of object to delete
        .PARAMETER definition
        Return related Definition
#>

function Global:Remove-OciByTypeAndId {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to delete",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related Definition")][Switch]$definition
    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/shares/$id/annotations"

            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve annotations for object
    .DESCRIPTION
     
    .PARAMETER id
    Id of object to retrieve
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=definition)
    .PARAMETER definition
    Return related Definition
#>

function Global:Get-OciByTypeAndId {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=definition)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/shares/$id/annotations"
           
            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Update annotations for object
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>

[
  {
    "rawValue": "Bronze",
    "definition": {
      "id": "4992",
    }
  }
]
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER definition
        Return related Definition
#>

function Global:Update-OciByTypeAndId {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=2,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/shares/$id/annotations"

            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PUT -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PUT to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Bulk un-assign applications from asset
    .DESCRIPTION
    Request body should contain a list of valid application ids, example: <br/>

<pre>
[
    {
        "id":"12345"
    },
    {
        "id":"67890"
    }
]
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER computeResources
        Return list of related Compute resources
        .PARAMETER storageResources
        Return list of related Storage resources
#>

function Global:Bulk-OciUnAssignApplicationsFromAsset {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/shares/$id/applications"

            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve the applications of object
    .DESCRIPTION
     
    .PARAMETER id
    Id of object to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER storageResources
    Return list of related Storage resources
#>

function Global:Get-OciByTypeAndId {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/shares/$id/applications"
 
            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Bulk assign applications to asset
    .DESCRIPTION
    Request body should contain a list of valid application ids, example: <br/>

<pre>
[
    {
        "id":"12345"
    },
    {
        "id":"67890"
    }
]
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER computeResources
        Return list of related Compute resources
        .PARAMETER storageResources
        Return list of related Storage resources
#>

function Global:Bulk-OciAssignApplicationsToAsset {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/shares/$id/applications"
 
            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PATCH -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PATCH to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Add applications for object
    .DESCRIPTION
    Request body should contain only one valid application id, example: <br/>

<pre>
{
    "id":"12345"
}
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER computeResources
        Return list of related Compute resources
        .PARAMETER storageResources
        Return list of related Storage resources
#>

function Global:Update-OciByTypeAndId {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/shares/$id/applications"
 
            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "POST to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Delete application from object
    .DESCRIPTION
     
    .PARAMETER id
    Id of object to delete application from
    .PARAMETER appId
    Id of application to delete from object
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER storageResources
    Return list of related Storage resources
#>

function Global:Remove-OciByTypeAndId {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to delete application from",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$True,
                    Position=1,
                    HelpMessage="Id of application to delete from object")][Long]$appId,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=4,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/shares/$id/applications/{appId}"
 
            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve qtree for given share
    .DESCRIPTION
     
    .PARAMETER id
    Id of share to retrieve qtree for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER internalVolume
    Return related Internal volume
    .PARAMETER shares
    Return list of related Shares
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER volumes
    Return list of related Volumes
#>

function Global:Get-OciQtree {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of share to retrieve qtree for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Internal volume")][Switch]$internalVolume,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Shares")][Switch]$shares,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Volumes")][Switch]$volumes,
        [parameter(Mandatory=$False,
                   Position=10,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/shares/$id/qtree"
           
            $switchparameters=@("storage","internalVolume","shares","annotations","applications","volumes")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve storage for given share
    .DESCRIPTION
     
    .PARAMETER id
    Id of share to retrieve storage for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storageNodes
    Return list of related Storage nodes
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER internalVolumes
    Return list of related Internal volumes
    .PARAMETER volumes
    Return list of related Volumes
    .PARAMETER qtrees
    Return list of related Qtrees
    .PARAMETER shares
    Return list of related Shares
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER disks
    Return list of related Disks
    .PARAMETER performance
    Return related Performance
    .PARAMETER protocols
    Return list of related Protocols
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciStorage {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of share to retrieve storage for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related Storage nodes")][Switch]$storageNodes,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Internal volumes")][Switch]$internalVolumes,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Volumes")][Switch]$volumes,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Qtrees")][Switch]$qtrees,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Shares")][Switch]$shares,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=14,
                    HelpMessage="Return list of related Disks")][Switch]$disks,
        [parameter(Mandatory=$False,
                    Position=15,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=16,
                    HelpMessage="Return list of related Protocols")][Switch]$protocols,
        [parameter(Mandatory=$False,
                    Position=17,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=18,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=19,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/shares/$id/storage"

            $switchparameters=@("storageNodes","storageResources","storagePools","internalVolumes","volumes","qtrees","shares","ports","datasources","annotations","disks","performance","protocols","applications","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve one storage node
    .DESCRIPTION
     
    .PARAMETER id
    Id of storage node to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER partner
    Return related HA partner
    .PARAMETER performance
    Return related Performance
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciStorageNode {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of storage node to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related HA partner")][Switch]$partner,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=12,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storageNodes/$id"
 
            $switchparameters=@("storage","partner","performance","datasources","storagePools","ports","annotations","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Delete annotations from object
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>

[
{
  "definition":{"id":"5001"}
},
{
  "definition":{"id":"5002"}
}
]
</pre>
                     
    .PARAMETER id
    Id of object to delete
        .PARAMETER definition
        Return related Definition
#>

function Global:Remove-OciAnnotationsByStorageNode {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to delete",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=2,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storageNodes/$id/annotations"

            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve annotations for object
    .DESCRIPTION
     
    .PARAMETER id
    Id of object to retrieve
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=definition)
        .PARAMETER definition
        Return related Definition
#>

function Global:Get-OciAnnotationsByStorageNode {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=definition)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storageNodes/$id/annotations"
 
            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
       
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Update annotations for object
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>

[
  {
    "rawValue": "Bronze",
    "definition": {
      "id": "4992",
    }
  }
]
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER definition
        Return related Definition
#>

function Global:Update-OciAnnotationsByStorageNode {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=2,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storageNodes/$id/annotations"

            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PUT -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PUT to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve one storage node datasources
    .DESCRIPTION
     
    .PARAMETER id
    Id of storage node to retrieve datasources for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER acquisitionUnit
    Return related Acquisition unit
    .PARAMETER note
    Return related Note
    .PARAMETER changes
    Return list of related Changes
    .PARAMETER packages
    Return list of related Packages
    .PARAMETER activePatch
    Return related Active patch
    .PARAMETER events
    Return list of related Events
    .PARAMETER devices
    Return list of related Devices
    .PARAMETER config
    Return related Config
#>

function Global:Get-OciDatasourcesByStorageNode {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of storage node to retrieve datasources for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Acquisition unit")][Switch]$acquisitionUnit,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Note")][Switch]$note,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Changes")][Switch]$changes,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Packages")][Switch]$packages,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return related Active patch")][Switch]$activePatch,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Events")][Switch]$events,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Devices")][Switch]$devices,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Config")][Switch]$config,
        [parameter(Mandatory=$False,
                   Position=12,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storageNodes/$id/datasources"
 
            $switchparameters=@("acquisitionUnit","note","changes","packages","activePatch","events","devices","config")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve one storage node performance
    .DESCRIPTION
     
    .PARAMETER id
    Id of storage node to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER history
    Return list of related History
#>

function Global:Get-OciStorageNodePerformance {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of storage node to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related History")][Switch]$history,
        [parameter(Mandatory=$False,
                   Position=5,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storageNodes/$id/performance"

            $switchparameters=@("history")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all ports by node
    .DESCRIPTION
     
    .PARAMETER id
    Id of storage node to retrieve ports for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER device
    Return related Device Object
    .PARAMETER fabrics
    Return list of related Fabrics
    .PARAMETER performance
    Return related Performance
    .PARAMETER connectedPorts
    Return list of related Connected ports
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciPortsByStorageNode {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of storage node to retrieve ports for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Device Object")][Switch]$device,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Fabrics")][Switch]$fabrics,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Connected ports")][Switch]$connectedPorts,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=12,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storageNodes/$id/ports"
 
            $switchparameters=@("device","fabrics","performance","connectedPorts","annotations","datasources","applications","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all storage pools by node
    .DESCRIPTION
     
    .PARAMETER id
    Id of storage node to retrieve storage pool for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER performance
    Return related Performance
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER internalVolumes
    Return list of related Internal volumes
    .PARAMETER volumes
    Return list of related Volumes
    .PARAMETER disks
    Return list of related Disks
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER storageNodes
    Return list of related Storage nodes
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciStoragePoolsByNode {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of storage node to retrieve storage pool for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Internal volumes")][Switch]$internalVolumes,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Volumes")][Switch]$volumes,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Disks")][Switch]$disks,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return list of related Storage nodes")][Switch]$storageNodes,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=14,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storageNodes/$id/storagePools"
 
            $switchparameters=@("storage","performance","storageResources","internalVolumes","volumes","disks","datasources","storageNodes","annotations","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve one storage pool
    .DESCRIPTION
     
    .PARAMETER id
    Id of storage pool to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER performance
    Return related Performance
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER internalVolumes
    Return list of related Internal volumes
    .PARAMETER volumes
    Return list of related Volumes
    .PARAMETER disks
    Return list of related Disks
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER storageNodes
    Return list of related Storage nodes
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciStoragePool {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of storage pool to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Internal volumes")][Switch]$internalVolumes,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Volumes")][Switch]$volumes,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Disks")][Switch]$disks,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return list of related Storage nodes")][Switch]$storageNodes,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storagePools/$id"
 
            $switchparameters=@("storage","performance","storageResources","internalVolumes","volumes","disks","datasources","storageNodes","annotations","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Delete annotations from object
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>

[
{
  "definition":{"id":"5001"}
},
{
  "definition":{"id":"5002"}
}
]
</pre>
                     
    .PARAMETER id
    Id of object to delete
        .PARAMETER definition
        Return related Definition
#>

function Global:Remove-OciAnnotationsByStoragePool {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to delete",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=2,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storagePools/$id/annotations"
            
            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: "
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve annotations for object
    .DESCRIPTION
     
    .PARAMETER id
    Id of object to retrieve
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=definition)
    .PARAMETER definition
    Return related Definition
#>

function Global:Get-OciAnnotationsByStoragePool {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=definition)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storagePools/$id/annotations"
 
            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Update annotations for object
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>

[
  {
    "rawValue": "Bronze",
    "definition": {
      "id": "4992",
    }
  }
]
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER definition
        Return related Definition
#>

function Global:Update-OciAnnotationsByStoragePool {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=2,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storagePools/$id/annotations"

            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PUT -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PUT to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve one storage pool datasources
    .DESCRIPTION
     
    .PARAMETER id
    Id of storage pool to retrieve datasources for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER acquisitionUnit
    Return related Acquisition unit
    .PARAMETER note
    Return related Note
    .PARAMETER changes
    Return list of related Changes
    .PARAMETER packages
    Return list of related Packages
    .PARAMETER activePatch
    Return related Active patch
    .PARAMETER events
    Return list of related Events
    .PARAMETER devices
    Return list of related Devices
    .PARAMETER config
    Return related Config
#>

function Global:Get-OciDatasourcesByStoragePool {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of storage pool to retrieve datasources for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Acquisition unit")][Switch]$acquisitionUnit,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Note")][Switch]$note,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Changes")][Switch]$changes,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Packages")][Switch]$packages,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return related Active patch")][Switch]$activePatch,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Events")][Switch]$events,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Devices")][Switch]$devices,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Config")][Switch]$config,
        [parameter(Mandatory=$False,
                   Position=12,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storagePools/$id/datasources"
 
            $switchparameters=@("acquisitionUnit","note","changes","packages","activePatch","events","devices","config")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve Disks for storage pool
    .DESCRIPTION
     
    .PARAMETER id
    Id of storage pool to retrieve disks for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER performance
    Return related Performance
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER backendVolumes
    Return list of related Backend volumes
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciDisksByStoragePool {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of storage pool to retrieve disks for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Backend volumes")][Switch]$backendVolumes,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=12,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storagePools/$id/disks"
 
            $switchparameters=@("storage","storagePools","performance","storageResources","backendVolumes","annotations","datasources","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve internal volumes for storage pool
    .DESCRIPTION
     
    .PARAMETER id
    Id of storage pool to retrieve internal volumes for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER performance
    Return related Performance
    .PARAMETER dataStores
    Return list of related Datastores
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER storagePool
    Return related Storage pool
    .PARAMETER volumes
    Return list of related Volumes
    .PARAMETER storageNodes
    Return list of related Storage nodes
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER replicaSources
    Return list of related Replica sources
    .PARAMETER qtrees
    Return list of related Qtrees
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciInternalVolumesByStoragePool {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of storage pool to retrieve internal volumes for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Datastores")][Switch]$dataStores,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return related Storage pool")][Switch]$storagePool,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Volumes")][Switch]$volumes,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return list of related Storage nodes")][Switch]$storageNodes,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=14,
                    HelpMessage="Return list of related Replica sources")][Switch]$replicaSources,
        [parameter(Mandatory=$False,
                    Position=15,
                    HelpMessage="Return list of related Qtrees")][Switch]$qtrees,
        [parameter(Mandatory=$False,
                    Position=16,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=17,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storagePools/$id/internalVolumes"
 
            $switchparameters=@("storage","performance","dataStores","computeResources","applications","storagePool","volumes","storageNodes","annotations","datasources","replicaSources","qtrees","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve one storage pool performance
    .DESCRIPTION
     
    .PARAMETER id
    Id of storage pool to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
        .PARAMETER history
        Return list of related History
#>

function Global:Get-OciStoragePoolPerformance {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of storage pool to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related History")][Switch]$history,
        [parameter(Mandatory=$False,
                   Position=5,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storagePools/$id/performance"
 
            $switchparameters=@("history")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve one storage pool storage
    .DESCRIPTION
     
    .PARAMETER id
    Id of storage pool to retrieve storage for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storageNodes
    Return list of related Storage nodes
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER internalVolumes
    Return list of related Internal volumes
    .PARAMETER volumes
    Return list of related Volumes
    .PARAMETER qtrees
    Return list of related Qtrees
    .PARAMETER shares
    Return list of related Shares
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER disks
    Return list of related Disks
    .PARAMETER performance
    Return related Performance
    .PARAMETER protocols
    Return list of related Protocols
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciStorageByStoragePool {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of storage pool to retrieve storage for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related Storage nodes")][Switch]$storageNodes,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Internal volumes")][Switch]$internalVolumes,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Volumes")][Switch]$volumes,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Qtrees")][Switch]$qtrees,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Shares")][Switch]$shares,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=14,
                    HelpMessage="Return list of related Disks")][Switch]$disks,
        [parameter(Mandatory=$False,
                    Position=15,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=16,
                    HelpMessage="Return list of related Protocols")][Switch]$protocols,
        [parameter(Mandatory=$False,
                    Position=17,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=18,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=19,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storagePools/$id/storage"
 
            $switchparameters=@("storageNodes","storageResources","storagePools","internalVolumes","volumes","qtrees","shares","ports","datasources","annotations","disks","performance","protocols","applications","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve storage nodes for storage pool
    .DESCRIPTION
     
    .PARAMETER id
    Id of storage pool to retrieve storage nodes for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER partner
    Return related HA partner
    .PARAMETER performance
    Return related Performance
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciStorageNodesByStoragePool {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of storage pool to retrieve storage nodes for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related HA partner")][Switch]$partner,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=12,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storagePools/$id/storageNodes"
 
            $switchparameters=@("storage","partner","performance","datasources","storagePools","ports","annotations","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve resources for storage pool
    .DESCRIPTION
     
    .PARAMETER id
    Id of storage pool to retrieve resources for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER performance
    Return related Performance
    .PARAMETER dataStores
    Return list of related Datastores
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciStorageResourcesByStoragePool {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of storage pool to retrieve resources for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Datastores")][Switch]$dataStores,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=11,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storagePools/$id/storageResources"
 
            $switchparameters=@("storage","performance","dataStores","computeResources","applications","storagePools","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve volumes for storage pool
    .DESCRIPTION
     
    .PARAMETER id
    Id of storage pool to retrieve volumes for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER performance
    Return related Performance
    .PARAMETER dataStores
    Return list of related Datastores
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER virtualStoragePools
    Return list of related Virtual storage pools
    .PARAMETER virtualizer
    Return related Virtualizer
    .PARAMETER internalVolume
    Return related Internal volume
    .PARAMETER autoTierPolicy
    Return related Auto tier policy
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER storageNodes
    Return list of related Storage nodes
    .PARAMETER replicaSources
    Return list of related Replica sources
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER qtree
    Return related Qtree
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciVolumesByStoragePool {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of storage pool to retrieve volumes for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Datastores")][Switch]$dataStores,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Virtual storage pools")][Switch]$virtualStoragePools,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Virtualizer")][Switch]$virtualizer,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return related Internal volume")][Switch]$internalVolume,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return related Auto tier policy")][Switch]$autoTierPolicy,
        [parameter(Mandatory=$False,
                    Position=14,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=15,
                    HelpMessage="Return list of related Storage nodes")][Switch]$storageNodes,
        [parameter(Mandatory=$False,
                    Position=16,
                    HelpMessage="Return list of related Replica sources")][Switch]$replicaSources,
        [parameter(Mandatory=$False,
                    Position=17,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=18,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=19,
                    HelpMessage="Return related Qtree")][Switch]$qtree,
        [parameter(Mandatory=$False,
                    Position=20,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=21,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storagePools/$id/volumes"
 
            $switchparameters=@("storage","performance","dataStores","computeResources","applications","storagePools","virtualStoragePools","virtualizer","internalVolume","autoTierPolicy","ports","storageNodes","replicaSources","datasources","annotations","qtree","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all storages
    .DESCRIPTION
     
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER sort
    Filter for sorting by metric/s
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER limit
    Number of storages per page.
    .PARAMETER offset
    Offset to be used with limit
    .PARAMETER storageNodes
    Return list of related Storage nodes
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER internalVolumes
    Return list of related Internal volumes
    .PARAMETER volumes
    Return list of related Volumes
    .PARAMETER qtrees
    Return list of related Qtrees
    .PARAMETER shares
    Return list of related Shares
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER disks
    Return list of related Disks
    .PARAMETER performance
    Return related Performance
    .PARAMETER protocols
    Return list of related Protocols
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciStorages {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                    Position=0,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for sorting by metric/s")][String]$sort,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Number of storages per page.")][Long]$limit,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Offset to be used with limit")][Long]$offset,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Storage nodes")][Switch]$storageNodes,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Internal volumes")][Switch]$internalVolumes,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Volumes")][Switch]$volumes,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return list of related Qtrees")][Switch]$qtrees,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return list of related Shares")][Switch]$shares,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=14,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=15,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=16,
                    HelpMessage="Return list of related Disks")][Switch]$disks,
        [parameter(Mandatory=$False,
                    Position=17,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=18,
                    HelpMessage="Return list of related Protocols")][Switch]$protocols,
        [parameter(Mandatory=$False,
                    Position=19,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=20,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=21,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $Uri = $Server.BaseUri + "/rest/v1/assets/storages"
           
        $switchparameters=@("storageNodes","storageResources","storagePools","internalVolumes","volumes","qtrees","shares","ports","datasources","annotations","disks","performance","protocols","applications","performancehistory")
        foreach ($parameter in $switchparameters) {
            if ((Get-Variable $parameter).Value) {
                if ($expand) {
                    $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                }
                else {
                    $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                }
            }
        }
 
        if ($fromTime -or $toTime -or $expand) {
            $Uri += '?'
            $Separator = ''
            if ($fromTime) {
                $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                $Separator = '&'
            }
            if ($toTime) {
                $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                $Separator = '&'
            }
            if ($expand) {
                $Uri += "$($Separator)expand=$expand"
            }
        }
 
        try {
            $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
        }
        catch {
            $ResponseBody = ParseExceptionBody $_.Exception.Response
            Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
        }
 
        if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
            $Result = ParseJsonString($Result.Trim())
        }
       
        Write-Output $Result
    }
}

<#
    .SYNOPSIS
    Retrieve total count of storages.
    .DESCRIPTION
     
 
#>

function Global:Get-OciStorageCount {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                   Position=0,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storages/count"
 
            try {
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve one storage
    .DESCRIPTION
     
    .PARAMETER id
    Id of storage to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storageNodes
    Return list of related Storage nodes
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER internalVolumes
    Return list of related Internal volumes
    .PARAMETER volumes
    Return list of related Volumes
    .PARAMETER qtrees
    Return list of related Qtrees
    .PARAMETER shares
    Return list of related Shares
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER disks
    Return list of related Disks
    .PARAMETER performance
    Return related Performance
    .PARAMETER protocols
    Return list of related Protocols
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciStorage {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of storage to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related Storage nodes")][Switch]$storageNodes,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Internal volumes")][Switch]$internalVolumes,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Volumes")][Switch]$volumes,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Qtrees")][Switch]$qtrees,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Shares")][Switch]$shares,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=14,
                    HelpMessage="Return list of related Disks")][Switch]$disks,
        [parameter(Mandatory=$False,
                    Position=15,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=16,
                    HelpMessage="Return list of related Protocols")][Switch]$protocols,
        [parameter(Mandatory=$False,
                    Position=17,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=18,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=19,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storages/$id"
 
            $switchparameters=@("storageNodes","storageResources","storagePools","internalVolumes","volumes","qtrees","shares","ports","datasources","annotations","disks","performance","protocols","applications","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Delete annotations from object
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>

[
{
  "definition":{"id":"5001"}
},
{
  "definition":{"id":"5002"}
}
]
</pre>
                     
    .PARAMETER id
    Id of object to delete
        .PARAMETER definition
        Return related Definition
#>

function Global:Remove-OciAnnotationsByStorage {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to delete",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=2,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storages/$id/annotations"
 

            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve annotations for object
    .DESCRIPTION
     
    .PARAMETER id
    Id of object to retrieve
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=definition)
    .PARAMETER definition
    Return related Definition
#>

function Global:Get-OciAnnotationsByStorage {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=definition)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storages/$id/annotations"
 
            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Update annotations for object
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>

[
  {
    "rawValue": "Bronze",
    "definition": {
      "id": "4992",
    }
  }
]
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER definition
        Return related Definition
#>

function Global:Update-OciAnnotationsByStorage {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=2,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storages/$id/annotations"

            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PUT -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PUT to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Bulk un-assign applications from asset
    .DESCRIPTION
    Request body should contain a list of valid application ids, example: <br/>

<pre>
[
    {
        "id":"12345"
    },
    {
        "id":"67890"
    }
]
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER computeResources
        Return list of related Compute resources
        .PARAMETER storageResources
        Return list of related Storage resources
#>

function Global:Bulk-OciUnAssignApplicationsFromAsset {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storages/$id/applications"

            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: "
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve the applications of object
    .DESCRIPTION
     
    .PARAMETER id
    Id of object to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER storageResources
    Return list of related Storage resources
#>

function Global:Get-OciByTypeAndId {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=6,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storages/$id/applications"
 
            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Bulk assign applications to asset
    .DESCRIPTION
    Request body should contain a list of valid application ids, example: <br/>

<pre>
[
    {
        "id":"12345"
    },
    {
        "id":"67890"
    }
]
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER computeResources
        Return list of related Compute resources
        .PARAMETER storageResources
        Return list of related Storage resources
#>

function Global:Bulk-OciAssignApplicationsToAsset {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storages/$id/applications"

            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PATCH -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PATCH to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Add applications for object
    .DESCRIPTION
    Request body should contain only one valid application id, example: <br/>

<pre>
{
    "id":"12345"
}
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER computeResources
        Return list of related Compute resources
        .PARAMETER storageResources
        Return list of related Storage resources
#>

function Global:Update-OciByTypeAndId {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storages/$id/applications"

            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "POST to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve datasources of a storage.
    .DESCRIPTION
     
    .PARAMETER id
    Id of storage to retrieve datasources for.
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER acquisitionUnit
    Return related Acquisition unit
    .PARAMETER note
    Return related Note
    .PARAMETER changes
    Return list of related Changes
    .PARAMETER packages
    Return list of related Packages
    .PARAMETER activePatch
    Return related Active patch
    .PARAMETER events
    Return list of related Events
    .PARAMETER devices
    Return list of related Devices
    .PARAMETER config
    Return related Config
#>

function Global:Get-OciDatasourcesByStorage {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of storage to retrieve datasources for.",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Acquisition unit")][Switch]$acquisitionUnit,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Note")][Switch]$note,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Changes")][Switch]$changes,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Packages")][Switch]$packages,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return related Active patch")][Switch]$activePatch,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Events")][Switch]$events,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Devices")][Switch]$devices,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Config")][Switch]$config,
        [parameter(Mandatory=$False,
                   Position=12,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storages/$id/datasources"
 
            $switchparameters=@("acquisitionUnit","note","changes","packages","activePatch","events","devices","config")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
       
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve disks for one storage
    .DESCRIPTION
     
    .PARAMETER id
    Id of storage to retrieve disks for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER performance
    Return related Performance
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER backendVolumes
    Return list of related Backend volumes
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciDisksByStorage {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of storage to retrieve disks for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Backend volumes")][Switch]$backendVolumes,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=12,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storages/$id/disks"
 
            $switchparameters=@("storage","storagePools","performance","storageResources","backendVolumes","annotations","datasources","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve internal volumes for one storage
    .DESCRIPTION
     
    .PARAMETER id
    Id of storage to retrieve internal volumes for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER performance
    Return related Performance
    .PARAMETER dataStores
    Return list of related Datastores
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER storagePool
    Return related Storage pool
    .PARAMETER volumes
    Return list of related Volumes
    .PARAMETER storageNodes
    Return list of related Storage nodes
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER replicaSources
    Return list of related Replica sources
    .PARAMETER qtrees
    Return list of related Qtrees
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciInternalVolumesByStorage {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of storage to retrieve internal volumes for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Datastores")][Switch]$dataStores,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return related Storage pool")][Switch]$storagePool,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Volumes")][Switch]$volumes,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return list of related Storage nodes")][Switch]$storageNodes,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=14,
                    HelpMessage="Return list of related Replica sources")][Switch]$replicaSources,
        [parameter(Mandatory=$False,
                    Position=15,
                    HelpMessage="Return list of related Qtrees")][Switch]$qtrees,
        [parameter(Mandatory=$False,
                    Position=16,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=21,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storages/$id/internalVolumes"
 
            $switchparameters=@("storage","performance","dataStores","computeResources","applications","storagePool","volumes","storageNodes","annotations","datasources","replicaSources","qtrees","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
      
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve one storage performance
    .DESCRIPTION
     
    .PARAMETER id
    Id of storage to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER history
    Return list of related History
#>

function Global:Get-OciStoragePerformance {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of storage to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related History")][Switch]$history,
        [parameter(Mandatory=$False,
                   Position=5,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storages/$id/performance"
 
           
            $switchparameters=@("history")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve storage ports for one storage
    .DESCRIPTION
     
    .PARAMETER id
    Id of storage to retrieve storage ports for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER device
    Return related Device Object
    .PARAMETER fabrics
    Return list of related Fabrics
    .PARAMETER performance
    Return related Performance
    .PARAMETER connectedPorts
    Return list of related Connected ports
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciPortsByStorage {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of storage to retrieve storage ports for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Device Object")][Switch]$device,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Fabrics")][Switch]$fabrics,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Connected ports")][Switch]$connectedPorts,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=12,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storages/$id/ports"
 
           
            $switchparameters=@("device","fabrics","performance","connectedPorts","annotations","datasources","applications","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve protocols of a storage.
    .DESCRIPTION
     
    .PARAMETER id
    Id of storage to retrieve protocols for.
#>

function Global:Get-OciProtocolsByStorage {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of storage to retrieve protocols for.",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                   Position=1,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storages/$id/protocols"
 
            $switchparameters=@("")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve storage qtrees for one storage
    .DESCRIPTION
     
    .PARAMETER id
    Id of storage to retrieve storage qtrees for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER internalVolume
    Return related Internal volume
    .PARAMETER shares
    Return list of related Shares
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER volumes
    Return list of related Volumes
#>

function Global:Get-OciQtreesByStorage {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of storage to retrieve storage qtrees for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Internal volume")][Switch]$internalVolume,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Shares")][Switch]$shares,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Volumes")][Switch]$volumes,
        [parameter(Mandatory=$False,
                   Position=10,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storages/$id/qtrees"
 
            $switchparameters=@("storage","internalVolume","shares","annotations","applications","volumes")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve storage shares for one storage
    .DESCRIPTION
     
    .PARAMETER id
    Id of storage to retrieve storage shares for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER qtree
    Return related Qtree
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER applications
    Return list of related Applications
#>

function Global:Get-OciSharesByStorage {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of storage to retrieve storage shares for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Qtree")][Switch]$qtree,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                   Position=8,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storages/$id/shares"
 
            $switchparameters=@("storage","qtree","annotations","applications")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve storage nodes for one storage
    .DESCRIPTION
     
    .PARAMETER id
    Id of storage to retrieve storage nodes for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER partner
    Return related HA partner
    .PARAMETER performance
    Return related Performance
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciStorageNodesByStorage {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of storage to retrieve storage nodes for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related HA partner")][Switch]$partner,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=12,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storages/$id/storageNodes"
 
           
            $switchparameters=@("storage","partner","performance","datasources","storagePools","ports","annotations","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve storage pools for one storage
    .DESCRIPTION
     
    .PARAMETER id
    Id of storage to retrieve storage pools for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER performance
    Return related Performance
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER internalVolumes
    Return list of related Internal volumes
    .PARAMETER volumes
    Return list of related Volumes
    .PARAMETER disks
    Return list of related Disks
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER storageNodes
    Return list of related Storage nodes
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciStoragePoolsByStorage {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of storage to retrieve storage pools for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Internal volumes")][Switch]$internalVolumes,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Volumes")][Switch]$volumes,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Disks")][Switch]$disks,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return list of related Storage nodes")][Switch]$storageNodes,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=14,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storages/$id/storagePools"
 
            $switchparameters=@("storage","performance","storageResources","internalVolumes","volumes","disks","datasources","storageNodes","annotations","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve storage resources for one storage
    .DESCRIPTION
     
    .PARAMETER id
    Id of storage to retrieve storage resources for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER performance
    Return related Performance
    .PARAMETER dataStores
    Return list of related Datastores
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciStorageResourcesByStorage {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of storage to retrieve storage resources for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Datastores")][Switch]$dataStores,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=11,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storages/$id/storageResources"

            $switchparameters=@("storage","performance","dataStores","computeResources","applications","storagePools","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve volumes for one storage
    .DESCRIPTION
     
    .PARAMETER id
    Id of storage to retrieve volumes for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER performance
    Return related Performance
    .PARAMETER dataStores
    Return list of related Datastores
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER virtualStoragePools
    Return list of related Virtual storage pools
    .PARAMETER virtualizer
    Return related Virtualizer
    .PARAMETER internalVolume
    Return related Internal volume
    .PARAMETER autoTierPolicy
    Return related Auto tier policy
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER storageNodes
    Return list of related Storage nodes
    .PARAMETER replicaSources
    Return list of related Replica sources
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER qtree
    Return related Qtree
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciVolumesByStorage {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of storage to retrieve volumes for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Datastores")][Switch]$dataStores,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Virtual storage pools")][Switch]$virtualStoragePools,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Virtualizer")][Switch]$virtualizer,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return related Internal volume")][Switch]$internalVolume,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return related Auto tier policy")][Switch]$autoTierPolicy,
        [parameter(Mandatory=$False,
                    Position=14,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=15,
                    HelpMessage="Return list of related Storage nodes")][Switch]$storageNodes,
        [parameter(Mandatory=$False,
                    Position=16,
                    HelpMessage="Return list of related Replica sources")][Switch]$replicaSources,
        [parameter(Mandatory=$False,
                    Position=17,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=18,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=19,
                    HelpMessage="Return related Qtree")][Switch]$qtree,
        [parameter(Mandatory=$False,
                    Position=20,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=4,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/storages/$id/volumes"

            $switchparameters=@("storage","performance","dataStores","computeResources","applications","storagePools","virtualStoragePools","virtualizer","internalVolume","autoTierPolicy","ports","storageNodes","replicaSources","datasources","annotations","qtree","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
       
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all Switches
    .DESCRIPTION
     
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER limit
    Number of switches per page.
    .PARAMETER offset
    Offset to be used with limit
    .PARAMETER fabric
    Return related Fabric
    .PARAMETER performance
    Return related Performance
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciSwitches {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                    Position=0,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Number of switches per page.")][Long]$limit,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Offset to be used with limit")][Long]$offset,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Fabric")][Switch]$fabric,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=12,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/switches"

            $switchparameters=@("fabric","performance","ports","annotations","datasources","applications","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve total count of switches.
    .DESCRIPTION
     
 
#>

function Global:Get-OciSwitchCount {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $Uri = $Server.BaseUri + "/rest/v1/assets/switches/count"
 
        try {
            $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
        }
        catch {
            $ResponseBody = ParseExceptionBody $_.Exception.Response
            Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
        }
 
        if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
            $Result = ParseJsonString($Result.Trim())
        }

        Write-Output $Result
    }
}

<#
    .SYNOPSIS
    Retrieve one switch
    .DESCRIPTION
     
    .PARAMETER id
    Id of switch to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER fabric
    Return related Fabric
    .PARAMETER performance
    Return related Performance
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciSwitch {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of switch to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Fabric")][Switch]$fabric,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=11,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/switches/$id"

            $switchparameters=@("fabric","performance","ports","annotations","datasources","applications","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Delete annotations from object
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>

[
{
  "definition":{"id":"5001"}
},
{
  "definition":{"id":"5002"}
}
]
</pre>
                     
    .PARAMETER id
    Id of object to delete
        .PARAMETER definition
        Return related Definition
#>

function Global:Remove-OciAnnotationsBySwitch {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to delete",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related Definition")][Switch]$definition
    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/switches/$id/annotations"

            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve annotations for object
    .DESCRIPTION
     
    .PARAMETER id
    Id of object to retrieve
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=definition)
        .PARAMETER definition
        Return related Definition
#>

function Global:Get-OciAnnotationsBySwitch {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=definition)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/switches/$id/annotations"
 
            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Update annotations for object
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>

[
  {
    "rawValue": "Bronze",
    "definition": {
      "id": "4992",
    }
  }
]
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER definition
        Return related Definition
#>

function Global:Update-OciAnnotationsBySwitch {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=2,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/switches/$id/annotations"

            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                    Write-Verbose "Body: $Body"
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PUT -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PUT to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Bulk un-assign applications from asset
    .DESCRIPTION
    Request body should contain a list of valid application ids, example: <br/>

<pre>
[
    {
        "id":"12345"
    },
    {
        "id":"67890"
    }
]
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER computeResources
        Return list of related Compute resources
        .PARAMETER storageResources
        Return list of related Storage resources
#>

function Global:Bulk-OciUnAssignApplicationsFromAsset {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/switches/$id/applications"
 
            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: "
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve the applications of object
    .DESCRIPTION
     
    .PARAMETER id
    Id of object to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER storageResources
    Return list of related Storage resources
#>

function Global:Get-OciByTypeAndId {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=6,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/switches/$id/applications"

            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
       
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Bulk assign applications to asset
    .DESCRIPTION
    Request body should contain a list of valid application ids, example: <br/>

<pre>
[
    {
        "id":"12345"
    },
    {
        "id":"67890"
    }
]
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER computeResources
        Return list of related Compute resources
        .PARAMETER storageResources
        Return list of related Storage resources
#>

function Global:Bulk-OciAssignApplicationsToAsset {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/switches/$id/applications"
 
            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PATCH -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PATCH to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Add applications for object
    .DESCRIPTION
    Request body should contain only one valid application id, example: <br/>

<pre>
{
    "id":"12345"
}
</pre>
             
    .PARAMETER id
    Id of object to update
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER storageResources
    Return list of related Storage resources
#>

function Global:Update-OciByTypeAndId {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources
    )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/switches/$id/applications"

            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "POST to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve datasources of a switch.
    .DESCRIPTION
     
    .PARAMETER id
    Id of switch to retrieve datasources for.
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER acquisitionUnit
    Return related Acquisition unit
    .PARAMETER note
    Return related Note
    .PARAMETER changes
    Return list of related Changes
    .PARAMETER packages
    Return list of related Packages
    .PARAMETER activePatch
    Return related Active patch
    .PARAMETER events
    Return list of related Events
    .PARAMETER devices
    Return list of related Devices
    .PARAMETER config
    Return related Config
#>

function Global:Get-OciDatasourcesBySwitch {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of switch to retrieve datasources for.",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Acquisition unit")][Switch]$acquisitionUnit,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Note")][Switch]$note,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Changes")][Switch]$changes,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Packages")][Switch]$packages,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return related Active patch")][Switch]$activePatch,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Events")][Switch]$events,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Devices")][Switch]$devices,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Config")][Switch]$config,
        [parameter(Mandatory=$False,
                   Position=12,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/switches/$id/datasources"
 
            $switchparameters=@("acquisitionUnit","note","changes","packages","activePatch","events","devices","config")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve one fabric from switch
    .DESCRIPTION
     
    .PARAMETER id
    Id of switch.
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=portSummary)
        .PARAMETER switches
        Return list of related Switches
        .PARAMETER datasources
        Return list of related Datasources
#>

function Global:Get-OciFabricBySwitch {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of switch.",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=portSummary)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related Switches")][Switch]$switches,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                   Position=6,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/switches/$id/fabric"

            $switchparameters=@("switches","datasources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve one switch performance.
    .DESCRIPTION
     
    .PARAMETER id
    Id of switch.
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=portSummary)
    .PARAMETER history
    Return list of related History
#>

function Global:Get-OciSwitchPerformance {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of switch.",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=portSummary)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related History")][Switch]$history,
        [parameter(Mandatory=$False,
                   Position=5,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/switches/$id/performance"

            $switchparameters=@("history")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve switch ports for one switch
    .DESCRIPTION
     
    .PARAMETER id
    Id of switch to retrieve switch ports for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER device
    Return related Device Object
    .PARAMETER fabrics
    Return list of related Fabrics
    .PARAMETER performance
    Return related Performance
    .PARAMETER connectedPorts
    Return list of related Connected ports
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciPortsBySwitch {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of switch to retrieve switch ports for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Device Object")][Switch]$device,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Fabrics")][Switch]$fabrics,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Connected ports")][Switch]$connectedPorts,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=12,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/switches/$id/ports"
 
            $switchparameters=@("device","fabrics","performance","connectedPorts","annotations","datasources","applications","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all Virtual Machines
    .DESCRIPTION
     
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER sort
    Filter for sorting by metric/s
    .PARAMETER limit
    Number of virtual machines per page.
    .PARAMETER offset
    Offset to be used with limit
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER performance
    Return related Performance
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER fileSystems
    Return list of related File systems
    .PARAMETER dataStore
    Return related Datastore
    .PARAMETER host
    Return related Host
    .PARAMETER vmdks
    Return list of related Vmdks
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciVirtualMachines {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                    Position=0,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for sorting by metric/s")][String]$sort,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Number of virtual machines per page.")][Long]$limit,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Offset to be used with limit")][Long]$offset,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related File systems")][Switch]$fileSystems,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return related Datastore")][Switch]$dataStore,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Host")][Switch]$host,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return list of related Vmdks")][Switch]$vmdks,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=14,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=15,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=16,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=17,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/virtualMachines"

            $switchparameters=@("performance","ports","storageResources","fileSystems","dataStore","host","vmdks","applications","annotations","datasources","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            $VirtualMachines = ParseVirtualMachines($Result)
            Write-Output $VirtualMachines
        }
    }
}

<#
    .SYNOPSIS
    Retrieve total count of Virtual Machines
    .DESCRIPTION
     
 
#>

function Global:Get-OciVirtualMachineCount {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                   Position=0,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $Uri = $Server.BaseUri + "/rest/v1/assets/virtualMachines/count"
 
        try {
            $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
        }
        catch {
            $ResponseBody = ParseExceptionBody $_.Exception.Response
            Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
        }
 
        if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
            $Result = ParseJsonString($Result.Trim())
        }
           
        Write-Output $Result
    }
}

<#
    .SYNOPSIS
    Retrieve one Virtual Machine
    .DESCRIPTION
     
    .PARAMETER id
    Id of virtual machine to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER performance
    Return related Performance
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER fileSystems
    Return list of related File systems
    .PARAMETER dataStore
    Return related Datastore
    .PARAMETER host
    Return related Host
    .PARAMETER vmdks
    Return list of related Vmdks
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciVirtualMachine {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of virtual machine to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related File systems")][Switch]$fileSystems,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return related Datastore")][Switch]$dataStore,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return related Host")][Switch]$host,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Vmdks")][Switch]$vmdks,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=14,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=15,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/virtualMachines/$id"

            $switchparameters=@("performance","ports","storageResources","fileSystems","dataStore","host","vmdks","applications","annotations","datasources","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            $VirtualMachine = ParseVirtualMachines($Result)
            Write-Output $VirtualMachine
        }
    }
}

<#
    .SYNOPSIS
    Delete annotations from object
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>

[
{
  "definition":{"id":"5001"}
},
{
  "definition":{"id":"5002"}
}
]
</pre>
                     
    .PARAMETER id
    Id of object to delete
        .PARAMETER definition
        Return related Definition
#>

function Global:Remove-OciAnnotationsByVirtualMachine {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to delete",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=2,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/virtualMachines/$id/annotations"

            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
       
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve annotations for object
    .DESCRIPTION
     
    .PARAMETER id
    Id of object to retrieve
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=definition)
        .PARAMETER definition
        Return related Definition
#>

function Global:Get-OciAnnotationsByVirtualMachine {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=definition)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/virtualMachines/$id/annotations"
 
           
            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Update annotations for object
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>

[
  {
    "rawValue": "Bronze",
    "definition": {
      "id": "4992",
    }
  }
]
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER definition
        Return related Definition
#>

function Global:Update-OciAnnotationsByVirtualMachine {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=2,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/virtualMachines/$id/annotations"

            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PUT -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PUT to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Bulk un-assign applications from asset
    .DESCRIPTION
    Request body should contain a list of valid application ids, example: <br/>

<pre>
[
    {
        "id":"12345"
    },
    {
        "id":"67890"
    }
]
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER computeResources
        Return list of related Compute resources
        .PARAMETER storageResources
        Return list of related Storage resources
#>

function Global:Bulk-OciUnAssignApplicationsFromAsset {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/virtualMachines/$id/applications"

            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve the applications of object
    .DESCRIPTION
     
    .PARAMETER id
    Id of object to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER storageResources
    Return list of related Storage resources
#>

function Global:Get-OciApplicationsByVirtualMachine {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=6,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/virtualMachines/$id/applications"
 
            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Bulk assign applications to asset
    .DESCRIPTION
    Request body should contain a list of valid application ids, example: <br/>

<pre>
[
    {
        "id":"12345"
    },
    {
        "id":"67890"
    }
]
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER computeResources
        Return list of related Compute resources
        .PARAMETER storageResources
        Return list of related Storage resources
#>

function Global:Bulk-OciAssignApplicationsToAsset {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/virtualMachines/$id/applications"
 
            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PATCH -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PATCH to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Add applications for object
    .DESCRIPTION
    Request body should contain only one valid application id, example: <br/>

<pre>
{
    "id":"12345"
}
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER computeResources
        Return list of related Compute resources
        .PARAMETER storageResources
        Return list of related Storage resources
#>

function Global:Update-OciByTypeAndId {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/virtualMachines/$id/applications"

            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "POST to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Delete application from object
    .DESCRIPTION
     
    .PARAMETER id
    Id of object to delete application from
    .PARAMETER appId
    Id of application to delete from object
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER storageResources
    Return list of related Storage resources
#>

function Global:Remove-OciByTypeAndId {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to delete application from",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$True,
                    Position=1,
                    HelpMessage="Id of application to delete from object")][Long]$appId,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=4,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/virtualMachines/$id/applications/$appId"

            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve one data store for virtual machine
    .DESCRIPTION
     
    .PARAMETER id
    Id of virtual machine to retrieve data store for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER performance
    Return related Performance
    .PARAMETER hosts
    Return list of related Hosts
    .PARAMETER vmdks
    Return list of related Vmdks
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciDataStoreByVirtualMachine {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of virtual machine to retrieve data store for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Hosts")][Switch]$hosts,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Vmdks")][Switch]$vmdks,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=11,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/virtualMachines/$id/dataStore"

            $switchparameters=@("performance","hosts","vmdks","datasources","storageResources","annotations","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve datasources of a virtual machine.
    .DESCRIPTION
     
    .PARAMETER id
    Id of virtual machine to retrieve datasources for.
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER acquisitionUnit
    Return related Acquisition unit
    .PARAMETER note
    Return related Note
    .PARAMETER changes
    Return list of related Changes
    .PARAMETER packages
    Return list of related Packages
    .PARAMETER activePatch
    Return related Active patch
    .PARAMETER events
    Return list of related Events
    .PARAMETER devices
    Return list of related Devices
    .PARAMETER config
    Return related Config
#>

function Global:Get-OciDatasourcesByVirtualMachine {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of virtual machine to retrieve datasources for.",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Acquisition unit")][Switch]$acquisitionUnit,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Note")][Switch]$note,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Changes")][Switch]$changes,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Packages")][Switch]$packages,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return related Active patch")][Switch]$activePatch,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Events")][Switch]$events,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Devices")][Switch]$devices,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Config")][Switch]$config,
        [parameter(Mandatory=$False,
                   Position=11,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/virtualMachines/$id/datasources"
 
            $switchparameters=@("acquisitionUnit","note","changes","packages","activePatch","events","devices","config")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all file systems by virtual machine
    .DESCRIPTION
     
    .PARAMETER id
    Id of virtual machine to retrieve file systems for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER vmdks
    Return list of related Vmdks
    .PARAMETER computeResource
    Return related Compute resource
#>

function Global:Get-OciFileSystemsByVirtualMachine {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of virtual machine to retrieve file systems for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Vmdks")][Switch]$vmdks,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return related Compute resource")][Switch]$computeResource,
        [parameter(Mandatory=$False,
                   Position=7,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/virtualMachines/$id/fileSystems"
 
            $switchparameters=@("storageResources","vmdks","computeResource")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve one virtual machine host
    .DESCRIPTION
     
    .PARAMETER id
    Id of virtual machine to retrieve host for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER performance
    Return related Performance
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER fileSystems
    Return list of related File systems
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER virtualMachines
    Return list of related Virtual machines
    .PARAMETER dataCenter
    Return related Data center
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER clusterHosts
    Return list of related Cluster hosts
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciHostByVirtualMachine {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of virtual machine to retrieve host for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related File systems")][Switch]$fileSystems,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Virtual machines")][Switch]$virtualMachines,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return related Data center")][Switch]$dataCenter,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return list of related Cluster hosts")][Switch]$clusterHosts,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=14,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=15,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/virtualMachines/$id/host"

            $switchparameters=@("performance","ports","storageResources","fileSystems","applications","virtualMachines","dataCenter","annotations","clusterHosts","datasources","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve one Virtual Machine Performance
    .DESCRIPTION
     
    .PARAMETER id
    Id of virtual machine to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
        .PARAMETER history
        Return list of related History
#>

function Global:Get-OciVirtualMachinePerformance {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of virtual machine to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related History")][Switch]$history,
        [parameter(Mandatory=$False,
                   Position=5,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/virtualMachines/$id/performance"
 
            $switchparameters=@("history")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            $Performance = ParsePerformance($Result)
            Write-Output $Performance
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all ports by virtual machine
    .DESCRIPTION
     
    .PARAMETER id
    Id of virtual machine to retrieve ports for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER device
    Return related Device Object
    .PARAMETER fabrics
    Return list of related Fabrics
    .PARAMETER performance
    Return related Performance
    .PARAMETER connectedPorts
    Return list of related Connected ports
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciPortsByVirtualMachine {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of virtual machine to retrieve ports for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Device Object")][Switch]$device,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Fabrics")][Switch]$fabrics,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Connected ports")][Switch]$connectedPorts,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=12,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/virtualMachines/$id/ports"
 
            $switchparameters=@("device","fabrics","performance","connectedPorts","annotations","datasources","applications","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all storage resources by virtual machine
    .DESCRIPTION
     
    .PARAMETER id
    Id of virtual machine to retrieve storage resources for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER performance
    Return related Performance
    .PARAMETER dataStores
    Return list of related Datastores
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciStorageResourcesByVirtualMachine {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of virtual machine to retrieve storage resources for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Datastores")][Switch]$dataStores,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=11,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/virtualMachines/$id/storageResources"

            $switchparameters=@("storage","performance","dataStores","computeResources","applications","storagePools","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve Vmdks for virtual machine
    .DESCRIPTION
     
    .PARAMETER id
    Id of virtual machine to retrieve disks for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER performance
    Return related Performance
    .PARAMETER dataStore
    Return related Datastore
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER virtualMachine
    Return related Virtual machine
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciVmdksByVirtualMachine {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of virtual machine to retrieve disks for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Datastore")][Switch]$dataStore,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return related Virtual machine")][Switch]$virtualMachine,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=11,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/virtualMachines/$id/vmdks"

            $switchparameters=@("performance","dataStore","storageResources","virtualMachine","annotations","datasources","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve one virtual machine Vmdk
    .DESCRIPTION
     
    .PARAMETER id
    Id of virtual machine disk to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER performance
    Return related Performance
    .PARAMETER dataStore
    Return related Datastore
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER virtualMachine
    Return related Virtual machine
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciVmdk {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of virtual machine disk to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Datastore")][Switch]$dataStore,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return related Virtual machine")][Switch]$virtualMachine,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=11,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/vmdks/$id"

            $switchparameters=@("performance","dataStore","storageResources","virtualMachine","annotations","datasources","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Delete annotations from object
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>

[
{
  "definition":{"id":"5001"}
},
{
  "definition":{"id":"5002"}
}
]
</pre>
                     
    .PARAMETER id
    Id of object to delete
        .PARAMETER definition
        Return related Definition
#>

function Global:Remove-OciAnnotationsByVmdk {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to delete",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=2,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/vmdks/$id/annotations"

            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve annotations for object
    .DESCRIPTION
     
    .PARAMETER id
    Id of object to retrieve
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=definition)
    .PARAMETER definition
    Return related Definition
#>

function Global:Get-OciAnnotationsByVmdk {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=definition)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/vmdks/$id/annotations"
 
            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Update annotations for object
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>

[
  {
    "rawValue": "Bronze",
    "definition": {
      "id": "4992",
    }
  }
]
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER definition
        Return related Definition
#>

function Global:Update-OciAnnotationsByVmdk {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=2,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/vmdks/$id/annotations"
 
            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: "
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PUT -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PUT to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve datasources of a vmdk.
    .DESCRIPTION
     
    .PARAMETER id
    Id of vmdk to retrieve datasources for.
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER acquisitionUnit
    Return related Acquisition unit
    .PARAMETER note
    Return related Note
    .PARAMETER changes
    Return list of related Changes
    .PARAMETER packages
    Return list of related Packages
    .PARAMETER activePatch
    Return related Active patch
    .PARAMETER events
    Return list of related Events
    .PARAMETER devices
    Return list of related Devices
    .PARAMETER config
    Return related Config
#>

function Global:Get-OciDatasourcesByVmdk {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of vmdk to retrieve datasources for.",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Acquisition unit")][Switch]$acquisitionUnit,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Note")][Switch]$note,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Changes")][Switch]$changes,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Packages")][Switch]$packages,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return related Active patch")][Switch]$activePatch,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Events")][Switch]$events,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Devices")][Switch]$devices,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Config")][Switch]$config,
        [parameter(Mandatory=$False,
                   Position=12,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/vmdks/$id/datasources"
 
           
            $switchparameters=@("acquisitionUnit","note","changes","packages","activePatch","events","devices","config")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve one Vmdk performance
    .DESCRIPTION
     
    .PARAMETER id
    Id of virtual machine disk to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER history
    Return list of related History
#>

function Global:Get-OciVmdkPerformance {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of virtual machine disk to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related History")][Switch]$history,
        [parameter(Mandatory=$False,
                   Position=5,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/vmdks/$id/performance"
 
           
            $switchparameters=@("history")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve storage resources for virtual machine disk
    .DESCRIPTION
     
    .PARAMETER id
    Id of virtual machine disk to retrieve storage resources for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER performance
    Return related Performance
    .PARAMETER dataStores
    Return list of related Datastores
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciStorageResourcesByVmdk {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of virtual machine disk to retrieve storage resources for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Datastores")][Switch]$dataStores,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=11,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/vmdks/$id/storageResources"
 
           
            $switchparameters=@("storage","performance","dataStores","computeResources","applications","storagePools","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve virtual machine for virtual machine disk
    .DESCRIPTION
     
    .PARAMETER id
    Id of virtual machine disk to retrieve virtual machine for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER performance
    Return related Performance
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER fileSystems
    Return list of related File systems
    .PARAMETER dataStore
    Return related Datastore
    .PARAMETER host
    Return related Host
    .PARAMETER vmdks
    Return list of related Vmdks
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciVirtualMachineByVmdk {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of virtual machine disk to retrieve virtual machine for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related File systems")][Switch]$fileSystems,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return related Datastore")][Switch]$dataStore,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return related Host")][Switch]$host,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Vmdks")][Switch]$vmdks,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=14,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=15,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/vmdks/$id/virtualMachine"

            $switchparameters=@("performance","ports","storageResources","fileSystems","dataStore","host","vmdks","applications","annotations","datasources","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve one volume
    .DESCRIPTION
     
    .PARAMETER id
    Id of volume to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER performance
    Return related Performance
    .PARAMETER dataStores
    Return list of related Datastores
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER virtualStoragePools
    Return list of related Virtual storage pools
    .PARAMETER virtualizer
    Return related Virtualizer
    .PARAMETER internalVolume
    Return related Internal volume
    .PARAMETER autoTierPolicy
    Return related Auto tier policy
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER storageNodes
    Return list of related Storage nodes
    .PARAMETER replicaSources
    Return list of related Replica sources
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER qtree
    Return related Qtree
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of volume to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Datastores")][Switch]$dataStores,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Virtual storage pools")][Switch]$virtualStoragePools,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Virtualizer")][Switch]$virtualizer,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return related Internal volume")][Switch]$internalVolume,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return related Auto tier policy")][Switch]$autoTierPolicy,
        [parameter(Mandatory=$False,
                    Position=14,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=15,
                    HelpMessage="Return list of related Storage nodes")][Switch]$storageNodes,
        [parameter(Mandatory=$False,
                    Position=16,
                    HelpMessage="Return list of related Replica sources")][Switch]$replicaSources,
        [parameter(Mandatory=$False,
                    Position=17,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=18,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=19,
                    HelpMessage="Return related Qtree")][Switch]$qtree,
        [parameter(Mandatory=$False,
                    Position=20,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=9,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/volumes/$id"

            $switchparameters=@("storage","performance","dataStores","computeResources","applications","storagePools","virtualStoragePools","virtualizer","internalVolume","autoTierPolicy","ports","storageNodes","replicaSources","datasources","annotations","qtree","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Delete annotations from object
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>

[
{
  "definition":{"id":"5001"}
},
{
  "definition":{"id":"5002"}
}
]
</pre>
                     
    .PARAMETER id
    Id of object to delete
        .PARAMETER definition
        Return related Definition
#>

function Global:Remove-OciAnnotationsByVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to delete",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=2,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/volumes/$id/annotations"

            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve annotations for object
    .DESCRIPTION
     
    .PARAMETER id
    Id of object to retrieve
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=definition)
    .PARAMETER definition
    Return related Definition
#>

function Global:Get-OciAnnotationsByVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=definition)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=3,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/volumes/$id/annotations"

            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Update annotations for object
    .DESCRIPTION
    Request body should be like JSON below: <br/>

<pre>

[
  {
    "rawValue": "Bronze",
    "definition": {
      "id": "4992",
    }
  }
]
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER definition
        Return related Definition
#>

function Global:Update-OciAnnotationsByVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Return related Definition")][Switch]$definition,
        [parameter(Mandatory=$False,
                   Position=2,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/volumes/$id/annotations"

            $switchparameters=@("definition")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ""
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PUT -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PUT to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Bulk un-assign applications from asset
    .DESCRIPTION
    Request body should contain a list of valid application ids, example: <br/>

<pre>
[
    {
        "id":"12345"
    },
    {
        "id":"67890"
    }
]
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER computeResources
        Return list of related Compute resources
        .PARAMETER storageResources
        Return list of related Storage resources
#>

function Global:Remove-OciApplicationsFromVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$True,
                    Position=1,
                    HelpMessage="List of application IDs",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][String[]]$applicationId,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=4,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/volumes/$id/applications"

            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ConvertTo-Json @($applicationId | % { @{id=$_} }) -Compress
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve the applications of object
    .DESCRIPTION
     
    .PARAMETER id
    Id of object to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER storageResources
    Return list of related Storage resources
#>

function Global:Get-OciApplicationsByVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=6,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/volumes/$id/applications"

            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Bulk assign applications to asset
    .DESCRIPTION
    Request body should contain a list of valid application ids, example: <br/>

<pre>
[
    {
        "id":"12345"
    },
    {
        "id":"67890"
    }
]
</pre>
             
    .PARAMETER id
    Id of object to update
        .PARAMETER computeResources
        Return list of related Compute resources
        .PARAMETER storageResources
        Return list of related Storage resources
#>

function Global:Add-OciApplicationsToVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$True,
                    Position=1,
                    HelpMessage="List of application IDs",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][String[]]$applicationId,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=4,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/volumes/$id/applications"
 
            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Body = ConvertTo-Json @($applicationId | % { @{id=$_} }) -Compress
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PATCH -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "PATCH to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Add applications for object
    .DESCRIPTION
    Request body should contain only one valid application id, example: <br/>

<pre>
{
    "id":"12345"
}
</pre>
             
    .PARAMETER id
    Id of object to update
    .PARAMETER applicationId
    Valid application id which should be associated
        .PARAMETER computeResources
        Return list of related Compute resources
        .PARAMETER storageResources
        Return list of related Storage resources
#>

function Global:Update-OciApplicationsByVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to update",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$True,
                    Position=1,
                    HelpMessage="Valid application id which should be associated")][String]$applicationId,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=4,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/volumes/$id/applications"
           
            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {                
                $Body = ConvertTo-Json ($applicationId | % { @{id=$_} }) -Compress
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method POST -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "POST to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
       
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Delete application from object
    .DESCRIPTION
     
    .PARAMETER id
    Id of object to delete application from
    .PARAMETER appId
    Id of application to delete from object
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER storageResources
    Return list of related Storage resources
#>

function Global:Remove-OciByTypeAndId {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of object to delete application from",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$True,
                    Position=1,
                    HelpMessage="Id of application to delete from object")][Long]$appId,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                   Position=4,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/volumes/$id/applications/$appId"
 
            $switchparameters=@("computeResources","storageResources")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method DELETE -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "DELETE to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve the auto tier policy name of a volume.
    .DESCRIPTION
     
    .PARAMETER id
    Id of the volume to retrieve the auto tier policy name.
#>

function Global:Get-OciAutoTierPolicyByVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of the volume to retrieve the auto tier policy name.",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                   Position=1,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/volumes/$id/autoTierPolicy"

            $switchparameters=@("")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all compute resources for a volume
    .DESCRIPTION
     
    .PARAMETER id
    Id of volume to retrieve compute resources for
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER performance
    Return related Performance
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER fileSystems
    Return list of related File systems
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciComputeResourcesByVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of volume to retrieve compute resources for",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related File systems")][Switch]$fileSystems,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=9,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/volumes/$id/computeResources"

            $switchparameters=@("performance","ports","storageResources","fileSystems","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all data stores for a given target volume.
    .DESCRIPTION
     
    .PARAMETER id
    Id of target volume to retrieve the data stores for.
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER performance
    Return related Performance
    .PARAMETER hosts
    Return list of related Hosts
    .PARAMETER vmdks
    Return list of related Vmdks
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciDatastoresByVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of target volume to retrieve the data stores for.",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Hosts")][Switch]$hosts,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Vmdks")][Switch]$vmdks,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=11,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/volumes/$id/dataStores"

            $switchparameters=@("performance","hosts","vmdks","datasources","storageResources","annotations","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
           
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve datasources of a volume.
    .DESCRIPTION
     
    .PARAMETER id
    Id of volume to retrieve datasources for.
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER acquisitionUnit
    Return related Acquisition unit
    .PARAMETER note
    Return related Note
    .PARAMETER changes
    Return list of related Changes
    .PARAMETER packages
    Return list of related Packages
    .PARAMETER activePatch
    Return related Active patch
    .PARAMETER events
    Return list of related Events
    .PARAMETER devices
    Return list of related Devices
    .PARAMETER config
    Return related Config
#>

function Global:Get-OciDatasourcesByVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of volume to retrieve datasources for.",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Acquisition unit")][Switch]$acquisitionUnit,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Note")][Switch]$note,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Changes")][Switch]$changes,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Packages")][Switch]$packages,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return related Active patch")][Switch]$activePatch,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Events")][Switch]$events,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Devices")][Switch]$devices,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Config")][Switch]$config,
        [parameter(Mandatory=$False,
                   Position=12,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/volumes/$id/datasources"

            $switchparameters=@("acquisitionUnit","note","changes","packages","activePatch","events","devices","config")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve internal volume for a given volume.
    .DESCRIPTION
     
    .PARAMETER id
    Id of volume to retrieve the internal volume.
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER performance
    Return related Performance
    .PARAMETER dataStores
    Return list of related Datastores
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER storagePool
    Return related Storage pool
    .PARAMETER volumes
    Return list of related Volumes
    .PARAMETER storageNodes
    Return list of related Storage nodes
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER replicaSources
    Return list of related Replica sources
    .PARAMETER qtrees
    Return list of related Qtrees
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciInternalVolumeByVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of volume to retrieve the internal volume.",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Datastores")][Switch]$dataStores,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return related Storage pool")][Switch]$storagePool,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Volumes")][Switch]$volumes,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return list of related Storage nodes")][Switch]$storageNodes,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=14,
                    HelpMessage="Return list of related Replica sources")][Switch]$replicaSources,
        [parameter(Mandatory=$False,
                    Position=15,
                    HelpMessage="Return list of related Qtrees")][Switch]$qtrees,
        [parameter(Mandatory=$False,
                    Position=16,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=17,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/volumes/$id/internalVolume"
 
            $switchparameters=@("storage","performance","dataStores","computeResources","applications","storagePool","volumes","storageNodes","annotations","datasources","replicaSources","qtrees","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve one volume performance
    .DESCRIPTION
     
    .PARAMETER id
    Id of volume to retrieve
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER history
    Return list of related History
#>

function Global:Get-OciVolumePerformance {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of volume to retrieve",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related History")][Switch]$history,
        [parameter(Mandatory=$False,
                   Position=5,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/volumes/$id/performance"
 
            $switchparameters=@("history")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all storage ports and their connected ports by volume.
    .DESCRIPTION
     
    .PARAMETER id
    Id of volume to retrieve the ports that are connected to storage ports.
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER device
    Return related Device Object
    .PARAMETER fabrics
    Return list of related Fabrics
    .PARAMETER performance
    Return related Performance
    .PARAMETER connectedPorts
    Return list of related Connected ports
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciPortsByVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of volume to retrieve the ports that are connected to storage ports.",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Device Object")][Switch]$device,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Fabrics")][Switch]$fabrics,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Connected ports")][Switch]$connectedPorts,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=12,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/volumes/$id/ports"

            $switchparameters=@("device","fabrics","performance","connectedPorts","annotations","datasources","applications","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve qtree for a given volume.
    .DESCRIPTION
     
    .PARAMETER id
    Id of volume to retrieve the qtree.
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER internalVolume
    Return related Internal volume
    .PARAMETER shares
    Return list of related Shares
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER volumes
    Return list of related Volumes
#>

function Global:Get-OciQtree {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of volume to retrieve the qtree.",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Internal volume")][Switch]$internalVolume,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Shares")][Switch]$shares,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Volumes")][Switch]$volumes,
        [parameter(Mandatory=$False,
                   Position=10,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/volumes/$id/qtree"
 
            $switchparameters=@("storage","internalVolume","shares","annotations","applications","volumes")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
       
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve all source volumes for a given target volume.
    .DESCRIPTION
     
    .PARAMETER id
    Id of target volume to retrieve the source volumes.
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER performance
    Return related Performance
    .PARAMETER dataStores
    Return list of related Datastores
    .PARAMETER computeResources
    Return list of related Compute resources
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER virtualStoragePools
    Return list of related Virtual storage pools
    .PARAMETER virtualizer
    Return related Virtualizer
    .PARAMETER internalVolume
    Return related Internal volume
    .PARAMETER autoTierPolicy
    Return related Auto tier policy
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER storageNodes
    Return list of related Storage nodes
    .PARAMETER replicaSources
    Return list of related Replica sources
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER qtree
    Return related Qtree
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciSourceVolumesByVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of target volume to retrieve the source volumes.",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Datastores")][Switch]$dataStores,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Compute resources")][Switch]$computeResources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Virtual storage pools")][Switch]$virtualStoragePools,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Virtualizer")][Switch]$virtualizer,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return related Internal volume")][Switch]$internalVolume,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return related Auto tier policy")][Switch]$autoTierPolicy,
        [parameter(Mandatory=$False,
                    Position=14,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=15,
                    HelpMessage="Return list of related Storage nodes")][Switch]$storageNodes,
        [parameter(Mandatory=$False,
                    Position=16,
                    HelpMessage="Return list of related Replica sources")][Switch]$replicaSources,
        [parameter(Mandatory=$False,
                    Position=17,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=18,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=19,
                    HelpMessage="Return related Qtree")][Switch]$qtree,
        [parameter(Mandatory=$False,
                    Position=20,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=21,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/volumes/$id/replicaSources"

            $switchparameters=@("storage","performance","dataStores","computeResources","applications","storagePools","virtualStoragePools","virtualizer","internalVolume","autoTierPolicy","ports","storageNodes","replicaSources","datasources","annotations","qtree","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve the storage of a volume.
    .DESCRIPTION
     
    .PARAMETER id
    Id of the volume to retrieve the storage.
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storageNodes
    Return list of related Storage nodes
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER internalVolumes
    Return list of related Internal volumes
    .PARAMETER volumes
    Return list of related Volumes
    .PARAMETER qtrees
    Return list of related Qtrees
    .PARAMETER shares
    Return list of related Shares
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER disks
    Return list of related Disks
    .PARAMETER performance
    Return related Performance
    .PARAMETER protocols
    Return list of related Protocols
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciStorageByVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of the volume to retrieve the storage.",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related Storage nodes")][Switch]$storageNodes,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Internal volumes")][Switch]$internalVolumes,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Volumes")][Switch]$volumes,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Qtrees")][Switch]$qtrees,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Shares")][Switch]$shares,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=14,
                    HelpMessage="Return list of related Disks")][Switch]$disks,
        [parameter(Mandatory=$False,
                    Position=15,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=16,
                    HelpMessage="Return list of related Protocols")][Switch]$protocols,
        [parameter(Mandatory=$False,
                    Position=17,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=18,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=19,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/volumes/$id/storage"

            $switchparameters=@("storageNodes","storageResources","storagePools","internalVolumes","volumes","qtrees","shares","ports","datasources","annotations","disks","performance","protocols","applications","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve storage nodes for a given volume.
    .DESCRIPTION
     
    .PARAMETER id
    Id of volume to retrieve the storage nodes.
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER partner
    Return related HA partner
    .PARAMETER performance
    Return related Performance
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciStorageNodesByVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of volume to retrieve the storage nodes.",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related HA partner")][Switch]$partner,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=12,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/volumes/$id/storageNodes"

            $switchparameters=@("storage","partner","performance","datasources","storagePools","ports","annotations","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve storage pools for a given volume.
    .DESCRIPTION
     
    .PARAMETER id
    Id of volume to retrieve the storage pools.
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER performance
    Return related Performance
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER internalVolumes
    Return list of related Internal volumes
    .PARAMETER volumes
    Return list of related Volumes
    .PARAMETER disks
    Return list of related Disks
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER storageNodes
    Return list of related Storage nodes
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciStoragePoolsByVolume {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of volume to retrieve the storage pools.",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Internal volumes")][Switch]$internalVolumes,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Volumes")][Switch]$volumes,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Disks")][Switch]$disks,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return list of related Storage nodes")][Switch]$storageNodes,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=14,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/volumes/$id/storagePools"

            $switchparameters=@("storage","performance","storageResources","internalVolumes","volumes","disks","datasources","storageNodes","annotations","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve virtual storage pools for a given volume.
    .DESCRIPTION
     
    .PARAMETER id
    Id of volume to retrieve the virtual storage pools.
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storage
    Return related Storage
    .PARAMETER performance
    Return related Performance
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER internalVolumes
    Return list of related Internal volumes
    .PARAMETER volumes
    Return list of related Volumes
    .PARAMETER disks
    Return list of related Disks
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER storageNodes
    Return list of related Storage nodes
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciVirtualStoragePools {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of volume to retrieve the virtual storage pools.",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return related Storage")][Switch]$storage,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Internal volumes")][Switch]$internalVolumes,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Volumes")][Switch]$volumes,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Disks")][Switch]$disks,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return list of related Storage nodes")][Switch]$storageNodes,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=14,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/volumes/$id/virtualStoragePools"

            $switchparameters=@("storage","performance","storageResources","internalVolumes","volumes","disks","datasources","storageNodes","annotations","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Retrieve virtualizer for a given backend volume.
    .DESCRIPTION
     
    .PARAMETER id
    Id of volume to retrieve the virtualizer.
    .PARAMETER fromTime
    Filter for time range, from time in milliseconds
    .PARAMETER toTime
    Filter for time range, to time in milliseconds
    .PARAMETER expand
    Expand parameter for underlying JSON object (e.g. expand=read,items)
    .PARAMETER storageNodes
    Return list of related Storage nodes
    .PARAMETER storageResources
    Return list of related Storage resources
    .PARAMETER storagePools
    Return list of related Storage pools
    .PARAMETER internalVolumes
    Return list of related Internal volumes
    .PARAMETER volumes
    Return list of related Volumes
    .PARAMETER qtrees
    Return list of related Qtrees
    .PARAMETER shares
    Return list of related Shares
    .PARAMETER ports
    Return list of related Ports
    .PARAMETER datasources
    Return list of related Datasources
    .PARAMETER annotations
    Return list of related Annotations
    .PARAMETER disks
    Return list of related Disks
    .PARAMETER performance
    Return related Performance
    .PARAMETER protocols
    Return list of related Protocols
    .PARAMETER applications
    Return list of related Applications
    .PARAMETER performancehistory
    Return related Performance History
#>

function Global:Get-OciVirtualizer {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of volume to retrieve the virtualizer.",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][Long[]]$id,
        [parameter(Mandatory=$False,
                    Position=1,
                    HelpMessage="Filter for time range, from time in milliseconds")][PSObject]$fromTime,
        [parameter(Mandatory=$False,
                    Position=2,
                    HelpMessage="Filter for time range, to time in milliseconds")][PSObject]$toTime,
        [parameter(Mandatory=$False,
                    Position=3,
                    HelpMessage="Expand parameter for underlying JSON object (e.g. expand=read,items)")][String]$expand,
        [parameter(Mandatory=$False,
                    Position=4,
                    HelpMessage="Return list of related Storage nodes")][Switch]$storageNodes,
        [parameter(Mandatory=$False,
                    Position=5,
                    HelpMessage="Return list of related Storage resources")][Switch]$storageResources,
        [parameter(Mandatory=$False,
                    Position=6,
                    HelpMessage="Return list of related Storage pools")][Switch]$storagePools,
        [parameter(Mandatory=$False,
                    Position=7,
                    HelpMessage="Return list of related Internal volumes")][Switch]$internalVolumes,
        [parameter(Mandatory=$False,
                    Position=8,
                    HelpMessage="Return list of related Volumes")][Switch]$volumes,
        [parameter(Mandatory=$False,
                    Position=9,
                    HelpMessage="Return list of related Qtrees")][Switch]$qtrees,
        [parameter(Mandatory=$False,
                    Position=10,
                    HelpMessage="Return list of related Shares")][Switch]$shares,
        [parameter(Mandatory=$False,
                    Position=11,
                    HelpMessage="Return list of related Ports")][Switch]$ports,
        [parameter(Mandatory=$False,
                    Position=12,
                    HelpMessage="Return list of related Datasources")][Switch]$datasources,
        [parameter(Mandatory=$False,
                    Position=13,
                    HelpMessage="Return list of related Annotations")][Switch]$annotations,
        [parameter(Mandatory=$False,
                    Position=14,
                    HelpMessage="Return list of related Disks")][Switch]$disks,
        [parameter(Mandatory=$False,
                    Position=15,
                    HelpMessage="Return related Performance")][Switch]$performance,
        [parameter(Mandatory=$False,
                    Position=16,
                    HelpMessage="Return list of related Protocols")][Switch]$protocols,
        [parameter(Mandatory=$False,
                    Position=17,
                    HelpMessage="Return list of related Applications")][Switch]$applications,
        [parameter(Mandatory=$False,
                    Position=18,
                    HelpMessage="Return related Performance History")][Switch]$performancehistory,
        [parameter(Mandatory=$False,
                   Position=19,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/assets/volumes/$id/virtualizer"

            $switchparameters=@("storageNodes","storageResources","storagePools","internalVolumes","volumes","qtrees","shares","ports","datasources","annotations","disks","performance","protocols","applications","performancehistory")
            foreach ($parameter in $switchparameters) {
                if ((Get-Variable $parameter).Value) {
                    if ($expand) {
                        $expand += ",$($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')"
                    }
                    else {
                        $expand = $($parameter -replace 'performancehistory','performance.history' -replace 'hostswitch','host')
                    }
                }
            }
 
            if ($fromTime -or $toTime -or $expand) {
                $Uri += '?'
                $Separator = ''
                if ($fromTime) {
                    $Uri += "fromTime=$($fromTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($toTime) {
                    $Uri += "$($Separator)toTime=$($toTime | ConvertTo-UnixTimestamp)"
                    $Separator = '&'
                }
                if ($expand) {
                    $Uri += "$($Separator)expand=$expand"
                }
            }
 
            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }

            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Search for OCI Objects
    .DESCRIPTION
    Search for OCI Objects
    .PARAMETER query
    Query parameter
#>

function Global:Search-Oci {
    [CmdletBinding()]
 
    PARAM (
            [parameter(Mandatory=$true,
                    Position=0,
                    HelpMessage="The search query expression parameter",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][string[]]$query,
        [parameter(Mandatory=$False,
                   Position=1,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }

    Process {
        foreach ($query in $query) {
            $Uri = $Server.BaseUri + "/rest/v1/search?query=$query"

            try {
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
 
            if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
                $Result = ParseJsonString($Result.Trim())
            }
       
            Write-Output $Result.resultsByCategory
        }
    }
}
<#
    .SYNOPSIS
    Retrieve OCI Server health status
    .DESCRIPTION
    Retrieve OCI Server health status
#>

function Global:Get-OciHealth {
    [CmdletBinding()]

    PARAM (
        [parameter(Mandatory=$False,
                   Position=1,
                   HelpMessage="OnCommand Insight Server.")]$Server=$CurrentOciServer
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $Uri = $Server.BaseUri + "/rest/v1/admin/health"
 
        try {
            $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
        }
        catch {
            $ResponseBody = ParseExceptionBody $_.Exception.Response
            Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
        }
 
        if (([String]$Result).Trim().startsWith('{') -or ([String]$Result).toString().Trim().startsWith('[')) {
            $Result = ParseJsonString($Result.Trim())
        }

        foreach ($Item in $Result) {
            $Item.time = $Item.time | ConvertFrom-UnixTimestamp
        }
       
        Write-Output $Result
    }
}

<#
    .SYNOPSIS
    Update OCI Datasource
    .DESCRIPTION
    Update OCI Datasource
#>

function Global:Update-OciDatasource {
    [CmdletBinding()]

    PARAM (
        [parameter(Mandatory=$True,
                    Position=0,
                    HelpMessage="Id of the datasource to be updated",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][String[]]$id,
        [parameter(Mandatory=$True,
                    Position=1,
                    HelpMessage="Datasource configuration",
                    ValueFromPipeline=$True,
                    ValueFromPipelineByPropertyName=$True)][PSObject[]]$config
        )
 
    Begin {
        $Result = $null
    }
   
    Process {
        $id = @($id)
        foreach ($id in $id) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/datasources/$id"
 
            try {
                $Body = ($config.config | ConvertTo-Json -Depth 10)
                Write-Verbose "Body: $Body"
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method PUT -Uri $Uri -Headers $Server.Headers -Body $Body -ContentType 'application/json'
                if ($Result.toString().startsWith('{')) {
                    $Result = ParseJsonString($Result)
                }
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
       
            Write-Output $Result
        }
    }
}

<#
    .SYNOPSIS
    Restore OCI Backup
    .DESCRIPTION
    Restore OCI Backup
#>

function Global:Restore-OciBackup {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                Position=0,
                HelpMessage="OnCommand Insight Server")][PSObject]$Server,
        [parameter(Mandatory=$True,
                Position=1,
                HelpMessage="Full path of OnCommand Insight Backup, either locally or on OnCommand Insight Server.",
                ValueFromPipeline=$True,
                ValueFromPipelineByPropertyName=$True)][PSObject[]]$FilePath
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $FilePath = @($FilePath)

        $StartTime = Get-Date

        foreach ($FilePath in $FilePath) {
            $Uri = $Server.BaseUri + "/rest/v1/admin/restore"

            if (Test-Path $FilePath) {
                Write-Host "Found local OCI Backup in $FilePath which will be restored"
                
                Write-Host "Starting Restore job. This can take several hours..."

                $Job = Start-Job {
                    Import-Module OnCommand-Insight

                    [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy

                    Invoke-MultipartFormDataUpload -InFile $args[0] -Uri $args[1] -Header $args[2]
                } -ArgumentList $FilePath,$URI,$Server.Headers
                
            }
            else {
                Write-Host "No local Backup in $FilePath, trying to restore backup residing on OnCommand Insight Server"
            
                # create boundary
                $boundary = [System.Guid]::NewGuid().ToString()
        
                # Linefeed character
                $LF = "`r`n"

                # Build Body for form-data manually since PS does not support multipart/form-data out of the box
                $Body = (
                    "--$boundary",
                    "Content-Disposition: form-data; name=`"backupFilePath`"$LF",
                    $FilePath,
                    "--$boundary--$LF"
                ) -join $LF

                Write-Host "Starting Restore job..."

                $Job = Start-Job {

                    Import-Module OnCommand-Insight

                    [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy

                    Invoke-RestMethod -Uri $args[0] -Timeout 864000000000 -Method Post -ContentType "multipart/form-data; boundary=`"$($args[1])`"" -Body $args[2] -Headers $args[3]
                } -ArgumentList $URI,$boundary,$Body,$Server.Headers
            }

            try {
                $percentComplete = 10
                $activity = "Restore started"
                $status = "Uploading"
                Write-Progress -Activity $activity -status $status -percentComplete $percentComplete
                sleep 2
                $i = 0
                while ($true) {
                    $ProgressUri = $Uri + "?_=" + (get-date | ConvertTo-UnixTimestamp)
                    $i++
                    $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $ProgressUri -Headers $Server.Headers -ErrorAction SilentlyContinue
                    if ($i -eq 1440) { 
                        Write-Host ''
                        throw 'Backup did not finish within 24 hours' 
                    }
                    if ($Result.status -eq 'SUCCESSFUL') {
                        Write-Host "finished"
                        return
                    }
                    elseif ($Result.status -eq 'FAILED' -and ($Result.currentStep.startTime | get-date) -ge $StartTime -or $Job.State -ne 'Running') {
                        return
                    }
                    elseif (($Result.currentStep.startTime | get-date) -ge $StartTime) {
                        $activity = $Result.currentStep.operationText
                        $status = $Result.components.name
                    }
                    switch ($Result.currentStep.phaseText) {
                        "Restoring" { $percentComplete = 20 }
                        "Waiting" { $percentComplete = 30 }
                    } 
                    Write-Progress -Activity $activity -status $status -percentComplete $percentComplete
                    sleep 5
                }
                Write-Progress -Activity $Result.currentStep.phaseText -status $Result.currentStep.operationText -percentComplete 100
                sleep 1
            }
            catch {
                $ResponseBody = ParseExceptionBody $_.Exception.Response
                Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
            }
        }
        Write-Output $Result
    }
}

<#
    .SYNOPSIS
    Get OCI Backup
    .DESCRIPTION
    Get OCI Backup
#>

function Global:Get-OciBackup {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                Position=0,
                HelpMessage="OnCommand Insight Server")][PSObject]$Server,
        [parameter(Mandatory=$True,
                Position=1,
                HelpMessage="Path where to store OnCommand Insight Backup.")][PSObject]$Path,
        [parameter(Mandatory=$False,
                Position=2,
                HelpMessage="Time in minutes to wait for backup to complete (Default = 60 minutes).")][PSObject]$Timeout=60
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $URI = $Server.BaseUri + "/rest/v1/admin/backups/current"
 
        Write-Host "Starting Backup"  
        $Job = Start-Job { 
            add-type @"
                    using System.Net;
                    using System.Security.Cryptography.X509Certificates;
                    public class TrustAllCertsPolicy : ICertificatePolicy {
                       public bool CheckValidationResult(
                            ServicePoint srvPoint, X509Certificate certificate,
                            WebRequest request, int certificateProblem) {
                            return true;
                        }
                    }
"@


            [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy

            [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

            Invoke-RestMethod -TimeoutSec 864000000000 -Method POST -Uri $args[0] -Headers $args[1] 
        } -ArgumentList $URI,$Server.Headers

        try {
            Write-Progress -Activity "Backup started" -status "Backing up" -percentComplete 0
            $i = 0
            while ($true) {
                $i++
                $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
                if ($i -eq ($Timeout * 12) -or $Job.State -ne 'Running') { 
                    Write-Progress -Activity "Backup did not complete in $Timeout minutes" -status "Backing failed" -percentComplete 100
                }
                if ($Result.status -eq 'SUCCESSFUL') { 
                    Write-Progress -Activity $Result -status $Result -percentComplete 100
                    sleep 1
                    break 
                }
                Write-Progress -Activity "Backup started" -status $Result.status -percentComplete (100*$i/($Timeout*12))
                sleep 5
            }
            $Uri = $($Server.BaseUri) + $Result.Url
        }
        catch {
            $ResponseBody = ParseExceptionBody $_.Exception.Response
            Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
        }

        $FilePath = $Path + '\' + (($Uri -split '/') | select -last 1)
        Write-Host $FilePath
        $Date = [datetime]::ParseExact($($FilePath -replace '.+_D(.*)_[0-9]+.zip','$1'),"yyyyMMdd_HHmm",$null)

        try {
            Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers -OutFile $FilePath
            Write-Host "Backup Saved to $FilePath"
            
            $Result = New-Object -TypeName PSCustomObject -ArgumentList @{FilePath=$FilePath;Date=$Date;URI=$Uri}

            Write-Output $Result
        }
        catch {
            $ResponseBody = ParseExceptionBody $_.Exception.Response
            Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
        }
    }
}

<#
    .SYNOPSIS
    Get OCI Backups
    .DESCRIPTION
    Get OCI Backups
#>

function Global:Get-OciBackups {
    [CmdletBinding()]
 
    PARAM (
        [parameter(Mandatory=$False,
                Position=0,
                HelpMessage="OnCommand Insight Server")][PSObject]$Server
    )
 
    Begin {
        $Result = $null
        if (!$Server) {
            throw "Server parameter not specified and no global OCI Server available. Run Connect-OciServer first!"
        }
    }
   
    Process {
        $Uri = $Server.BaseUri + "/rest/v1/admin/backups"
 
        try {
            $Result = Invoke-RestMethod -TimeoutSec $Server.Timeout -Method GET -Uri $Uri -Headers $Server.Headers
            
            $Result = $Result | % { [PSCustomObject]@{FilePath=$_.path;Date=($_.date | get-date)} }

            Write-Output $Result
        }
        catch {
            $ResponseBody = ParseExceptionBody $_.Exception.Response
            Write-Error "GET to $Uri failed with Exception $($_.Exception.Message) `n $responseBody"
        }
    }
}
# SIG # Begin signature block
# MIINjQYJKoZIhvcNAQcCoIINfjCCDXoCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUhMDdfJ4+Y3FD+Ni+W2gRPEm/
# 75CgggslMIIFezCCA2OgAwIBAgIKYShIlAAAAAAAAjANBgkqhkiG9w0BAQsFADAe
# MRwwGgYDVQQDExNOZXRBcHAgQ29ycCBSb290IENBMB4XDTEyMDUxODE2NTIxMFoX
# DTIyMDUxODE3MDIxMFowIzEhMB8GA1UEAxMYTmV0QXBwIENvcnAgSXNzdWluZyBD
# QSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2MmDX43gLgj2TSMd
# NNIEyfF3ocwpMehtRxzbVhh0usgFqCG6hPwX/6BdpfpNVGSTBkFm9Tyrg+M6/Tn4
# veTVFfUrDXtElob3lBvKBVxbDsH+fg3Khu3u5G8N4hIOsQGiWMOZBd+PNMYXbRtF
# 4ryjFjdEaRi2QEOdYLrEw8wufwc+HReIj3emD8ds8lw214RfJYALbmoJdhMq08LS
# EYMNq67QzT5ro94vaV/rkHwlt7B2I4noTY/HmsrQbtE60PkQhm9arVf3ozWk1jfu
# JY76N/EPwW9bbK4Oyaj5K9jC0tsy5bTP5tpbxnphh3yB5zIj8wbRN/x11Y+T0/3S
# hGq3EwIDAQABo4IBtDCCAbAwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFLug
# SJhI1LtuMzWzfWcohu0YYtLiMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsG
# A1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFLygHsSpAqdf
# 0xrxoztTANa5XBPnMIGDBgNVHR8EfDB6MHigdqB0hjhodHRwOi8vcGtpMS5uZXRh
# cHAuY29tL3BraS9OZXRBcHAlMjBDb3JwJTIwUm9vdCUyMENBLmNybIY4aHR0cDov
# L3BraTIubmV0YXBwLmNvbS9wa2kvTmV0QXBwJTIwQ29ycCUyMFJvb3QlMjBDQS5j
# cmwwgZwGCCsGAQUFBwEBBIGPMIGMMEQGCCsGAQUFBzAChjhodHRwOi8vcGtpMS5u
# ZXRhcHAuY29tL3BraS9OZXRBcHAlMjBDb3JwJTIwUm9vdCUyMENBLmNydDBEBggr
# BgEFBQcwAoY4aHR0cDovL3BraTIubmV0YXBwLmNvbS9wa2kvTmV0QXBwJTIwQ29y
# cCUyMFJvb3QlMjBDQS5jcnQwDQYJKoZIhvcNAQELBQADggIBADyIlLzbze/iZxXL
# U5FNTpxqmIWFyBcx3kXDEdptPT25P4iDVrZNn7IwRMSOiZ66xFLAOa4EBBDj/nE6
# RtYNQr0Gj3vyvevmabMyYu4KzG79pxD8uzHIDgd2GoMCtp51+HJ1vgPIZxjnKITj
# BoqeYfO3TLeBlWcdXNuds9Nw/HY5oFGPt5DTKoh1oMS/tVIhiLmyMNNoq2NTU5Wr
# y3Z7/Gbla2aCgiS8JtuMvi16x0fGV3H+LKltHcH+o9fO52scf8xZWjyX8WWTFFs+
# TZPuBV2ZIuKuwA3WeaN6SMJRhhMSBQPerWkKEpGLbG37zLgCy7PrLiKFHAzJ+9Pk
# lTxYqtRRp9ivaLTM8DH+d7Dftk5TQY3jTg5LoMTVyI/Y3bIOQJjkFM+Wkk84Mmb4
# k5ep/Xle9adOAqsP0neu5xec5T3z+WuvJmFqhOIQVcI8TpcdsEN636o9bdLX0M84
# Q6flDZiR+52u6GfMrFU0a3v/3VFkgl9Gh6gLryEyTAJt8RakCah9PzqGaUi33iRk
# UsYqIoTZeb/dw8Xqiae5zGyKNhNNfVkRtAlp0nUhT5cuy9tFPwn4Y5c1ZvuoNa9d
# bhUjWVWwvBtgYLzOh9uzEM6fef6SZDY7x0eN2WdpyXqXBncbQbvV2yuMttgJwG+7
# poWiuDt9JOk5LasRQDU8yZnECZf1MIIFojCCBIqgAwIBAgIKSyQl1QAAABQ3uzAN
# BgkqhkiG9w0BAQsFADAjMSEwHwYDVQQDExhOZXRBcHAgQ29ycCBJc3N1aW5nIENB
# IDEwHhcNMTQwOTE4MTU1NDE3WhcNMTgwOTE3MTU1NDE3WjCBlDETMBEGCgmSJomT
# 8ixkARkWA2NvbTEWMBQGCgmSJomT8ixkARkWBm5ldGFwcDESMBAGCgmSJomT8ixk
# ARkWAmhxMQ4wDAYDVQQLEwVTaXRlczENMAsGA1UECxMERU1FQTEOMAwGA1UECxMF
# VXNlcnMxIjAgBgNVBAMTGWZsb3JpYW5mLUZsb3JpYW4tRmVsZGhhdXMwggEiMA0G
# CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCY7ZvbPCSLrr5zr3V9trkHmycJyZ19
# ZZoNvxhLZ53Y2q544N1IRkftoFgj3OMtDv/RURUnOMnDxDQJenWmEoEMqt3tVSuS
# +fH4/6aOyOeXAhLLWwK0zYipzZxDDTudJH2h9MaGUDekd3/BYGdw8sVhg/0haMv2
# 6DWOKs3p4kHzyY59NGMq3OWSp0R1R7BYDpxRTK/isGl1QSsMrULgV8Kxdr/xo4qo
# C6pTyjy6Nr9F02EHEYyyerAptt5Ltl4YHLb1npOf25CzAqNUM8eggiLzgRp9cksD
# BkGTV69Jn8BrPeOfMBXK+IyQfhdFsxX57PMtywFFfCxg+j+WTtOIVUn/AgMBAAGj
# ggJkMIICYDALBgNVHQ8EBAMCB4AwPQYJKwYBBAGCNxUHBDAwLgYmKwYBBAGCNxUI
# gb3HUoOc8D2FlY0RhaigFIPWqF85g8Lxa4Gj1GYCAWQCAQYwHQYDVR0OBBYEFN+l
# AigDoThbz7+g+RTf6YexlkoMMB8GA1UdIwQYMBaAFLugSJhI1LtuMzWzfWcohu0Y
# YtLiMIGWBgNVHR8EgY4wgYswgYiggYWggYKGP2h0dHA6Ly9wa2kxLm5ldGFwcC5j
# b20vcGtpL05ldEFwcCUyMENvcnAlMjBJc3N1aW5nJTIwQ0ElMjAxLmNybIY/aHR0
# cDovL3BraTIubmV0YXBwLmNvbS9wa2kvTmV0QXBwJTIwQ29ycCUyMElzc3Vpbmcl
# MjBDQSUyMDEuY3JsMIHTBggrBgEFBQcBAQSBxjCBwzBLBggrBgEFBQcwAoY/aHR0
# cDovL3BraTEubmV0YXBwLmNvbS9wa2kvTmV0QXBwJTIwQ29ycCUyMElzc3Vpbmcl
# MjBDQSUyMDEuY3J0MEsGCCsGAQUFBzAChj9odHRwOi8vcGtpMi5uZXRhcHAuY29t
# L3BraS9OZXRBcHAlMjBDb3JwJTIwSXNzdWluZyUyMENBJTIwMS5jcnQwJwYIKwYB
# BQUHMAGGG2h0dHA6Ly9vY3NwLm5ldGFwcC5jb20vb2NzcDATBgNVHSUEDDAKBggr
# BgEFBQcDAzAbBgkrBgEEAYI3FQoEDjAMMAoGCCsGAQUFBwMDMDEGA1UdEQQqMCig
# JgYKKwYBBAGCNxQCA6AYDBZmbG9yaWFuZkBocS5uZXRhcHAuY29tMA0GCSqGSIb3
# DQEBCwUAA4IBAQAd3dk8TLL3HEBosUgpwq2Kw+DWQ4VG8wVTGdfinbWqedfryZfV
# gJjRwRCPwqbCATMENG8x34Q5u+0TG2ourFtnZAZRH5cdIiQCjOPuyhRLJxR/UpQV
# bGNTR04HKVAIjm6dGGXS+C4pgj+D5oq/RuZALkKnJNr4YnVbFjFbT7WX2PufxqYS
# L2nf28yNnUZH4WM4ntIAC2tPSTVbI+qVEJ47ezvlFmpbISznnYA7genG3yPNs/E/
# A/xgL5spxttUXSqQbAdNGJEJta1vw4jUEc3BlX4BDV+9EPcOgxzX3k/j6IxrdUxo
# D2OS+7Ipuiu8qS7gu3Fj7EdgH0eQcE23zLK5MYIB0jCCAc4CAQEwMTAjMSEwHwYD
# VQQDExhOZXRBcHAgQ29ycCBJc3N1aW5nIENBIDECCkskJdUAAAAUN7swCQYFKw4D
# AhoFAKB4MBgGCisGAQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJKoZIhvcNAQkDMQwG
# CisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwIwYJKoZI
# hvcNAQkEMRYEFGjE7TkGzuX3A1eH2zNhGyKJzLD4MA0GCSqGSIb3DQEBAQUABIIB
# ABHf/UJWolMd8TNBT+YEvpEVlu4JuKKYm09hNls0U2AhrVufp4xGmBwfccjDpast
# U4Dr4DSu1KWjc+hKx52XreJbczgMveHZiSfUyCFe47akYXpaTS65JhVhOwgxXi5U
# C5HgkhxGWSJrq3bYC8A11Y46ut0DO8++5HMajRlMxfuV7YLUPd6obTRRSpz7SSJl
# aQxZsEMoShEgHMKv1F8I5UWft+qDrejsCAYYsqeHrSxq7oiRvDmNma50vJD60GxY
# V2FbtXNQN3w1xJw3+1itOFVzUe1iCNtBKxkyLJl/OYwYzrcsm/ofNiBb7oe9agTJ
# pWfToRcNNApM3vjB6oCO52U=
# SIG # End signature block