Last active
March 11, 2024 21:24
-
-
Save JustinGrote/74af66cf3aaed3fcf201e729dd3c899f to your computer and use it in GitHub Desktop.
Commvault REST API Commands I will make into a Module Someday
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
Quickstart | |
------------------ | |
Get-Help Connect-CVServer -detailed | |
Get-Help Invoke-CVCommand -detailed | |
Connect-CVServer mycommvaultserver -force -verbose | |
Invoke-CVCommand 'Client' | |
Invoke-CVCommand 'Client/136' | |
#> | |
function Invoke-CVCommand { | |
[CmdletBinding(SupportsShouldProcess)] | |
param ( | |
#The path to the command relative to the API root. Examples: "Client","Client/{clientId}","Backupset" | |
[Parameter(Mandatory,ValueFromPipeline,Position=0)][String]$Command, | |
#Additional information to supply in the request. If it is a string, it is passed literally (e.g. an XML). If it is a hashtable, it will be converted to either HTTP GET parameters or POSTData, depending on the action selected | |
[Alias("ArgumentList")][Parameter()]$Body, | |
#Which HTTP Method to perform (GET, POST, or DELETE) | |
[ValidateSet("GET","POST","DELETE")][String]$Method = "GET", | |
#Specify the Base URI for the API. Used by Connect-CVServer. | |
[Parameter(ParameterSetName="Login")][URI]$URI | |
) | |
#Some special behavior for Login is required | |
if ($Command -eq "Login") {$isLogin = $true} | |
#Basic Status Checks | |
if (-not $isLogin) { | |
if (-not $SCRIPT:CVAPILogin) { | |
write-error "You must first connect to a Commvault system with Connect-CVServer." | |
return | |
} | |
if ((get-date) -gt ($SCRIPT:CVAPILoginExpireDate)) { | |
write-error "Your session has been inactive for more than 30 minutes, please log in again using Connect-CVServer" | |
return | |
} | |
} | |
$IRMParams = @{ | |
UseBasicParsing = $true | |
Headers = @{ | |
Accept = 'application/json' | |
} | |
ContentType = 'application/json' | |
Method = $Method | |
Body = $Body | |
} | |
#Login requests don't have an Auth token to give, obviously | |
if (-not $isLogin) { | |
$IRMParams.Headers.Authtoken = $SCRIPT:CVAPILogin.token | |
$CVAPIBaseURI = $SCRIPT:CVAPIURI | |
$IRMParams.WebSession = $SCRIPT:CVAPIWebSession | |
} else { | |
#Without a trailing slash, URI command builder will replace it | |
if ($URI -notmatch '/$') { | |
write-warning "The API root provided ($URI) did not end in a trailing slash. Adding it as the API root requires one" | |
$URI = [uri]([string]$URI + '/') | |
} | |
$CVAPIBaseURI = $URI | |
$IRMParams.SessionVariable = 'CVAPIWebSessionTemp' | |
} | |
#I would use Join-Path here normally but it doesn't work for HTTP URIs | |
$IRMParams.URI = new-object URI ($CVAPIBaseURI,$Command) | |
if ($PSCmdlet.ShouldProcess($IRMParams.URI.Host,"Invoking Command $Command")) { | |
#TODO: Better Logic Here | |
if ($Force) { | |
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true } | |
} | |
$restResult = Invoke-Restmethod @IRMParams -ErrorAction 'stop' -ErrorVariable 'restError' | |
if ($Force) { | |
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $null } | |
} | |
#Put the web session in the script (module) scope | |
if ($CVAPIWebsessionTemp) {$GLOBAL:CVAPIWebSession = $CVIAPIWebSessionTemp} | |
if ($restResult.errList) { | |
write-error "Error returned from $Computername`: $($restResult.errList.errLogMessage)" | |
continue | |
} | |
} | |
$restResult | |
#Reset the clock on token since we used a command | |
$SCRIPT:CVAPILoginExpireDate = (get-date).AddMinutes(29) | |
} | |
function Connect-CVServer { | |
[CmdletBinding(SupportsShouldProcess)] | |
param ( | |
#Hostname of the Commvault System | |
[Parameter(Mandatory=$true,ValueFromPipeline)][String]$ComputerName, | |
#Credentials to Use. For Active Directory logins, you can specify in either NT format (DOMAIN\Username) or the email address of the user as configured in Commvault/AD. | |
[Parameter(Mandatory=$true)] | |
[System.Management.Automation.PSCredential]$Credential = (Get-Credential -Message "Enter your Commvault Credentials"), | |
#Specify which remote CommServe you wish to connect to (example: commserve_host_name*commserve_name). Default is the same one as ComputerName. | |
$CommServer = "", | |
#Override the default base URI. You shouldn't need to do this unless you have a special configuration, proxy, or custom port. Your URI must end in a trailing slash! | |
$URI = "https://$($ComputerName)/webconsole/api/", | |
#Force the login even if already logged in or SSL cert cannot be validated | |
[Switch]$Force, | |
#Provide the Credential Object Including the API token | |
[Switch]$Passthru, | |
#Go directly to the Tomcat webserver on port 81 rather than via Web Console. May be required for older Commvault versions before v11. WARNING: Login occurs in plaintext! | |
[Switch]$Direct | |
) | |
if ((get-date) -lt ($SCRIPT:CVAPILoginExpireDate) -and -not $Force) { | |
write-warning "You are already connected to $($SCRIPT:CVAPIURI.host) as $SCRIPT:CVAPILoginUserName. Use -Force to reconnect anyways." | |
return | |
} else { | |
$SCRIPT:CVAPILogin = $null | |
[String]$SCRIPT:CVAPILoginUserName = $null | |
[URI]$SCRIPT:CVAPIURI = $null | |
$SCRIPT:CVAPILoginExpireDate = $null | |
$SCRIPT:CVAPIWebSession = $null | |
} | |
if ($Direct) { | |
write-warning "WARNING: Direct Login Method passes username and password in cleartext. Only use this on a local trusted network." | |
$URI = "http://$($ComputerName):81/SearchSvc/CVWebService.svc/" | |
} | |
$LoginRequestBody = @{ | |
domain = $credential.GetNetworkCredential().domain | |
username = $credential.GetNetworkCredential().username | |
#Base64-encoded password | |
password = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($Credential.getNetworkCredential().password)) | |
commserver = $CommServer | |
} | convertto-json -compress | |
if ($PSCmdlet.ShouldProcess($Computername,"Connecting as $($Credential.username)")) { | |
$restResult = Invoke-CVCommand -Command 'Login' -Method 'POST' -URI $URI -Verbose:$VerbosePreference -ErrorVariable RestError -Body $LoginRequestBody | |
#Immediately remove plaintext credentials from memory once task is complete | |
Remove-Variable "LoginRequestBody" | |
if ($RestError) {continue} | |
if ($restResult.token) { | |
$SCRIPT:CVAPILogin = $RestResult | |
$SCRIPT:CVAPILoginUserName = $Credential.username | |
$SCRIPT:CVAPIURI = $URI | |
write-host -fore Green "Connected to $ComputerName as $($Credential.username) ($($RestResult.username))" | |
if ($passThru) { | |
$SCRIPT:CVAPILogin | |
} | |
} else { | |
write-error "No authentication token was received from $ComputerName. Review for any errors above and check your connectivity." | |
} | |
} | |
} | |
function Disconnect-CVServer { | |
$logoutresult = Invoke-CVCommand 'Logout' -Method POST | |
if ($logoutResult -eq 'User logged out') { | |
get-variable CVAPI* -Scope script | Remove-Variable -Scope Script | |
} else { | |
write-error "Did not receive a valid logout response when disconnecting. Check your connectivity." | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment