From 7c68afda2e8e391b9fcea04ac04fdeb6761b5475 Mon Sep 17 00:00:00 2001 From: Edw1nS1984 Date: Wed, 16 Apr 2025 11:46:06 +0200 Subject: [PATCH] Added token auth --- README.md | 6 +- src/Functions/Public/Connect-vROServer.ps1 | 137 +++++++++++++++--- src/Functions/Public/Invoke-vRORestMethod.ps1 | 11 +- .../actions-service/Export-vROAction.ps1 | 10 +- .../actions-service/Import-vROAction.ps1 | 10 +- .../Export-vROConfigurationElement.ps1 | 10 +- .../Import-vROConfigurationElement.ps1 | 10 +- .../packages-service/Export-vROPackage.ps1 | 10 +- .../packages-service/Import-vROPackage.ps1 | 11 +- .../plugin-service/Export-vROPlugin.ps1 | 10 +- .../plugin-service/Import-vROPlugin.ps1 | 11 +- .../Export-vROResourceElement.ps1 | 10 +- .../Import-vROResourceElement.ps1 | 10 +- .../workflow-service/Export-vROWorkflow.ps1 | 11 +- .../Export-vROWorkflowIcon.ps1 | 11 +- .../Export-vROWorkflowSchema.ps1 | 11 +- .../workflow-service/Import-vROWorkflow.ps1 | 10 +- 17 files changed, 255 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index dc28d22..ea49c04 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,8 @@ Note: this module is not in any way developed or supported by anyone officially ### vRealize Orchestrator |||| -| --- | --- | --- | -|6.1|7.0|7.0.1| +| --- | --- | --- | --- | +|6.1|7.0|7.0.1| 8.X | ### PowerShell Editions @@ -24,7 +24,7 @@ Note: this module is not in any way developed or supported by anyone officially ## Authentication -Currently PowervRO only supports basic Authentication. If you are using one of the other supported methods let us know. +Currently PowervRO only supports basic and token Authentication. If you are using one of the other supported methods let us know. ## Download diff --git a/src/Functions/Public/Connect-vROServer.ps1 b/src/Functions/Public/Connect-vROServer.ps1 index 6f62cde..ce3a00f 100644 --- a/src/Functions/Public/Connect-vROServer.ps1 +++ b/src/Functions/Public/Connect-vROServer.ps1 @@ -21,6 +21,9 @@ .PARAMETER Credential Credential object to connect with + .PARAMETER TokenAuth + Use Token Authentication instead of Basic Authentication. This is only available in vRO 8.x and above + .PARAMETER IgnoreCertRequirements Ignore requirements to use fully signed certificates @@ -50,6 +53,9 @@ .EXAMPLE Connect-vROServer -Server vro01.domain.local -Port 443 -Credential (Get-Credential) + .EXAMPLE + Connect-vROServer -Server vro01.domain.local -Port 443 -Credential (Get-Credential) -TokenAuth + #> [CmdletBinding(DefaultParametersetName="Username")][OutputType('System.Management.Automation.PSObject')] @@ -75,6 +81,9 @@ [ValidateNotNullOrEmpty()] [Management.Automation.PSCredential]$Credential, + [Parameter(Mandatory=$false)] + [Switch]$TokenAuth, + [Parameter(Mandatory=$false)] [Switch]$IgnoreCertRequirements, @@ -174,34 +183,114 @@ try { - # --- Set Encoded Password - $Auth = $Username + ':' + $ConnectionPassword - $Encoded = [System.Text.Encoding]::UTF8.GetBytes($Auth) - $EncodedPassword = [System.Convert]::ToBase64String($Encoded) - - # --- Create Output Object - $Script:vROConnection = [pscustomobject]@{ - - Server = "https://$($Server):$($Port)" - Username = $Username - EncodedPassword = $EncodedPassword - Version = $Null - APIVersion = $Null - SignedCertificates = $SignedCertificates - SslProtocol = $SslProtocolResult + if (!$TokenAuth) + { + # --- Set Encoded Password + $Auth = $Username + ':' + $ConnectionPassword + $Encoded = [System.Text.Encoding]::UTF8.GetBytes($Auth) + $EncodedPassword = [System.Convert]::ToBase64String($Encoded) + + # --- Create Output Object + $Script:vROConnection = [pscustomobject]@{ + + Server = "https://$($Server):$($Port)" + Username = $Username + EncodedPassword = $EncodedPassword + Version = $Null + APIVersion = $Null + SignedCertificates = $SignedCertificates + SslProtocol = $SslProtocolResult + } + + # --- Update vROConnection with version information + $VersionInfo = Get-vROVersion + $Script:vROConnection.Version = $VersionInfo.Version + $Script:vROConnection.APIVersion = $VersionInfo.APIVersion + + # --- Test the credentials provided + Write-Verbose -Message "Testing credentials" + $URI = "/vco/api/server/permissions" + Invoke-vRORestMethod -Method Get -URI $URI -ErrorAction Stop | Out-Null + + Write-Output $Script:vROConnection } + else + { + + # Create the body for the authentication request + $body = @{ + username = $Username + password = $ConnectionPassword + } | ConvertTo-Json -Depth 10 + + $refresh = @{ + uri = "https://$($Server):$($Port)/csp/gateway/am/api/login?access_token" + method = "POST" + body = $body + headers = @{ + "Content-Type" = "application/json" + } + } + + $refreshToken = (Invoke-RestMethod @refresh -ErrorAction Stop -OutVariable refreshResponse).refresh_token + if ($null -eq $refreshToken) { + Write-Error "Failed to obtain refresh token from vRO server." - # --- Update vROConnection with version information - $VersionInfo = Get-vROVersion - $Script:vROConnection.Version = $VersionInfo.Version - $Script:vROConnection.APIVersion = $VersionInfo.APIVersion + } - # --- Test the credentials provided - Write-Verbose -Message "Testing credentials" - $URI = "/vco/api/server/permissions" - Invoke-vRORestMethod -Method Get -URI $URI -ErrorAction Stop | Out-Null + # Retrieve the access token using the refresh token + + $bearerBody = @{ + refreshToken = $refreshToken + } | ConvertTo-Json -Depth 10 + + $bearer = @{ + uri = "https://$($Server):$($Port)/iaas/api/login" + method = "POST" + body = $bearerBody + headers = @{ + "Content-Type" = "application/json" + } + } + + $accessToken = (Invoke-RestMethod @bearer -ErrorAction Stop -OutVariable bearerResponse).token + if ($null -eq $accessToken) { + Write-Error "Failed to obtain access token from vRO server." + + } + + #prepare headers with bearer token + $headers = @{ + Authorization = "Bearer $accessToken" + "Content-Type" = "application/json" + } - Write-Output $Script:vROConnection + # --- Create Output Object + $Script:vROConnection = [pscustomobject]@{ + + Server = "https://$($Server):$($Port)" + Username = $Username + Token = $accessToken + AuthHeaders = $headers + Version = $Null + APIVersion = $Null + SignedCertificates = $SignedCertificates + SslProtocol = $SslProtocolResult + } + + # --- Update vROConnection with version information + $VersionInfo = Get-vROVersion + $Script:vROConnection.Version = $VersionInfo.Version + $Script:vROConnection.APIVersion = $VersionInfo.APIVersion + + # --- Test the credentials provided + Write-Verbose -Message "Testing credentials" + $URI = "/vco/api/server/permissions" + Invoke-vRORestMethod -Method Get -URI $URI -ErrorAction Stop | Out-Null + + Write-Output $Script:vROConnection + + } } catch [Exception]{ diff --git a/src/Functions/Public/Invoke-vRORestMethod.ps1 b/src/Functions/Public/Invoke-vRORestMethod.ps1 index 81f843b..2e7093a 100644 --- a/src/Functions/Public/Invoke-vRORestMethod.ps1 +++ b/src/Functions/Public/Invoke-vRORestMethod.ps1 @@ -101,7 +101,16 @@ if (-not $Script:vROConnection){ "Accept"="application/json"; "Content-Type" = "application/json"; - "Authorization" = "Basic $($Script:vROConnection.EncodedPassword)"; + + } + + # --- Add the Authorization header + if ($Script:vROConnection.token) + { + $Headers.Add("Authorization", "Bearer $($Script:vROConnection.Token)") + } + else { + $Headers.Add("Authorization", "Basic $($Script:vROConnection.EncodedPassword)") } } diff --git a/src/Functions/Public/actions-service/Export-vROAction.ps1 b/src/Functions/Public/actions-service/Export-vROAction.ps1 index d005505..fd3d44d 100644 --- a/src/Functions/Public/actions-service/Export-vROAction.ps1 +++ b/src/Functions/Public/actions-service/Export-vROAction.ps1 @@ -62,13 +62,21 @@ $Headers = @{ - "Authorization" = "Basic $($Script:vROConnection.EncodedPassword)"; "Accept" ="Application/zip"; "Accept-Encoding" = "gzip, deflate"; "Content-Type" = "Application/zip;charset=utf-8"; } + # --- Add the Authorization header + if ($Script:vROConnection.token) + { + $Headers.Add("Authorization", "Bearer $($Script:vROConnection.Token)") + } + else { + $Headers.Add("Authorization", "Basic $($Script:vROConnection.EncodedPassword)") + } + # --- Run vRO REST Request $Request = Invoke-vRORestMethod -Uri $URI -Method Get -Headers $Headers -WebRequest -Verbose:$VerbosePreference diff --git a/src/Functions/Public/actions-service/Import-vROAction.ps1 b/src/Functions/Public/actions-service/Import-vROAction.ps1 index cea2614..c402bb6 100644 --- a/src/Functions/Public/actions-service/Import-vROAction.ps1 +++ b/src/Functions/Public/actions-service/Import-vROAction.ps1 @@ -90,12 +90,20 @@ # --- Set custom headers for the request $Headers = @{ - "Authorization" = "Basic $($Script:vROConnection.EncodedPassword)"; "Accept" = "Application/json" "Accept-Encoding" = "gzip,deflate,sdch"; "Content-Type" = "multipart/form-data; boundary=$($Boundary)" } + # --- Add the Authorization header + if ($Script:vROConnection.token) + { + $Headers.Add("Authorization", "Bearer $($Script:vROConnection.Token)") + } + else { + $Headers.Add("Authorization", "Basic $($Script:vROConnection.EncodedPassword)") + } + if ($PSCmdlet.ShouldProcess($FileInfo.FullName)){ # --- Run vRO REST Request diff --git a/src/Functions/Public/configuration-service/Export-vROConfigurationElement.ps1 b/src/Functions/Public/configuration-service/Export-vROConfigurationElement.ps1 index 4d7201a..be37064 100644 --- a/src/Functions/Public/configuration-service/Export-vROConfigurationElement.ps1 +++ b/src/Functions/Public/configuration-service/Export-vROConfigurationElement.ps1 @@ -54,13 +54,21 @@ $Headers = @{ - "Authorization" = "Basic $($Script:vROConnection.EncodedPassword)"; "Accept" ="application/vcoobject+xml"; "Accept-Encoding" = "gzip, deflate"; "Content-Type" = "Application/vcoobject+xml;charset=utf-8"; } + # --- Add the Authorization header + if ($Script:vROConnection.token) + { + $Headers.Add("Authorization", "Bearer $($Script:vROConnection.Token)") + } + else { + $Headers.Add("Authorization", "Basic $($Script:vROConnection.EncodedPassword)") + } + # --- Run vRO REST Request $Request = Invoke-vRORestMethod -Uri $URI -Method Get -Headers $Headers -WebRequest -Verbose:$VerbosePreference diff --git a/src/Functions/Public/configuration-service/Import-vROConfigurationElement.ps1 b/src/Functions/Public/configuration-service/Import-vROConfigurationElement.ps1 index d96af08..ec649f5 100644 --- a/src/Functions/Public/configuration-service/Import-vROConfigurationElement.ps1 +++ b/src/Functions/Public/configuration-service/Import-vROConfigurationElement.ps1 @@ -71,12 +71,20 @@ # --- Set custom headers for the request $Headers = @{ - "Authorization" = "Basic $($Script:vROConnection.EncodedPassword)"; "Accept" = "Application/json" "Accept-Encoding" = "gzip,deflate,sdch"; "Content-Type" = "multipart/form-data; boundary=$($Boundary)" } + # --- Add the Authorization header + if ($Script:vROConnection.token) + { + $Headers.Add("Authorization", "Bearer $($Script:vROConnection.Token)") + } + else { + $Headers.Add("Authorization", "Basic $($Script:vROConnection.EncodedPassword)") + } + if ($PSCmdlet.ShouldProcess($FileInfo.FullName)){ # --- Run vRO REST Request diff --git a/src/Functions/Public/packages-service/Export-vROPackage.ps1 b/src/Functions/Public/packages-service/Export-vROPackage.ps1 index fe8b0e5..ec37a74 100644 --- a/src/Functions/Public/packages-service/Export-vROPackage.ps1 +++ b/src/Functions/Public/packages-service/Export-vROPackage.ps1 @@ -58,12 +58,20 @@ $Headers = @{ - "Authorization" = "Basic $($Script:vROConnection.EncodedPassword)"; "Accept" ="Application/zip"; "Accept-Encoding" = "gzip, deflate"; "Content-Type" = "Application/zip;charset=utf-8"; } + # --- Add the Authorization header + if ($Script:vROConnection.token) + { + $Headers.Add("Authorization", "Bearer $($Script:vROConnection.Token)") + } + else { + $Headers.Add("Authorization", "Basic $($Script:vROConnection.EncodedPassword)") + } + if ($PSBoundParameters.ContainsKey('DontExportConfigurationAttributeValues')){ $ExportConfigurationAttributeValues = 'false' diff --git a/src/Functions/Public/packages-service/Import-vROPackage.ps1 b/src/Functions/Public/packages-service/Import-vROPackage.ps1 index c185706..e1ad28e 100644 --- a/src/Functions/Public/packages-service/Import-vROPackage.ps1 +++ b/src/Functions/Public/packages-service/Import-vROPackage.ps1 @@ -129,13 +129,20 @@ # --- Set custom headers for the request $Headers = @{ - - "Authorization" = "Basic $($Script:vROConnection.EncodedPassword)"; "Accept" = "Application/json" "Accept-Encoding" = "gzip,deflate,sdch"; "Content-Type" = "multipart/form-data; boundary=$($Boundary)" } + # --- Add the Authorization header + if ($Script:vROConnection.token) + { + $Headers.Add("Authorization", "Bearer $($Script:vROConnection.Token)") + } + else { + $Headers.Add("Authorization", "Basic $($Script:vROConnection.EncodedPassword)") + } + if ($PSCmdlet.ShouldProcess($FileInfo.FullName)){ # --- Run vRO REST Request diff --git a/src/Functions/Public/plugin-service/Export-vROPlugin.ps1 b/src/Functions/Public/plugin-service/Export-vROPlugin.ps1 index 3f86762..5c0293c 100644 --- a/src/Functions/Public/plugin-service/Export-vROPlugin.ps1 +++ b/src/Functions/Public/plugin-service/Export-vROPlugin.ps1 @@ -62,12 +62,20 @@ $Headers = @{ - "Authorization" = "Basic $($Script:vROConnection.EncodedPassword)"; "Accept" ="Application/json"; "Content-Type" = "application/zip;charset=UTF-8"; } + # --- Add the Authorization header + if ($Script:vROConnection.token) + { + $Headers.Add("Authorization", "Bearer $($Script:vROConnection.Token)") + } + else { + $Headers.Add("Authorization", "Basic $($Script:vROConnection.EncodedPassword)") + } + # --- Run vRO REST Request Write-Verbose -Message "Receiving response. This may take some time depending on the size of the plugin.." $Request = Invoke-vRORestMethod -Uri $URI -Method Get -Headers $Headers -WebRequest -Verbose:$VerbosePreference diff --git a/src/Functions/Public/plugin-service/Import-vROPlugin.ps1 b/src/Functions/Public/plugin-service/Import-vROPlugin.ps1 index b2a0951..073c1b5 100644 --- a/src/Functions/Public/plugin-service/Import-vROPlugin.ps1 +++ b/src/Functions/Public/plugin-service/Import-vROPlugin.ps1 @@ -75,13 +75,20 @@ # --- Set custom headers for the request $Headers = @{ - - "Authorization" = "Basic $($Script:vROConnection.EncodedPassword)"; "Accept" = "Application/json" "Accept-Encoding" = "gzip,deflate,sdch"; "Content-Type" = "multipart/form-data; boundary=$($Boundary)" } + # --- Add the Authorization header + if ($Script:vROConnection.token) + { + $Headers.Add("Authorization", "Bearer $($Script:vROConnection.Token)") + } + else { + $Headers.Add("Authorization", "Basic $($Script:vROConnection.EncodedPassword)") + } + if ($PSCmdlet.ShouldProcess($FileInfo.FullName)){ # --- Run vRO REST Request diff --git a/src/Functions/Public/resource-service/Export-vROResourceElement.ps1 b/src/Functions/Public/resource-service/Export-vROResourceElement.ps1 index e7cb131..c37fa1f 100644 --- a/src/Functions/Public/resource-service/Export-vROResourceElement.ps1 +++ b/src/Functions/Public/resource-service/Export-vROResourceElement.ps1 @@ -75,11 +75,19 @@ $Headers = @{ - "Authorization" = "Basic $($Script:vROConnection.EncodedPassword)"; "Accept" =" application/octet-stream"; } + # --- Add the Authorization header + if ($Script:vROConnection.token) + { + $Headers.Add("Authorization", "Bearer $($Script:vROConnection.Token)") + } + else { + $Headers.Add("Authorization", "Basic $($Script:vROConnection.EncodedPassword)") + } + # --- Run vRO REST Request $Request = Invoke-vRORestMethod -Uri $URI -Method Get -Headers $Headers -WebRequest -Verbose:$VerbosePreference diff --git a/src/Functions/Public/resource-service/Import-vROResourceElement.ps1 b/src/Functions/Public/resource-service/Import-vROResourceElement.ps1 index 1549b85..3147ef7 100644 --- a/src/Functions/Public/resource-service/Import-vROResourceElement.ps1 +++ b/src/Functions/Public/resource-service/Import-vROResourceElement.ps1 @@ -70,12 +70,20 @@ # --- Set custom headers for the request $Headers = @{ - "Authorization" = "Basic $($Script:vROConnection.EncodedPassword)"; "Accept" = "Application/json" "Accept-Encoding" = "gzip,deflate,sdch"; "Content-Type" = "multipart/form-data; boundary=$($Boundary)" } + # --- Add the Authorization header + if ($Script:vROConnection.token) + { + $Headers.Add("Authorization", "Bearer $($Script:vROConnection.Token)") + } + else { + $Headers.Add("Authorization", "Basic $($Script:vROConnection.EncodedPassword)") + } + if ($PSCmdlet.ShouldProcess($FileInfo.FullName)){ # --- Run vRO REST Request diff --git a/src/Functions/Public/workflow-service/Export-vROWorkflow.ps1 b/src/Functions/Public/workflow-service/Export-vROWorkflow.ps1 index 70a98fa..97b4150 100644 --- a/src/Functions/Public/workflow-service/Export-vROWorkflow.ps1 +++ b/src/Functions/Public/workflow-service/Export-vROWorkflow.ps1 @@ -44,11 +44,20 @@ $Headers = @{ - "Authorization" = "Basic $($Script:vROConnection.EncodedPassword)"; "Accept" ="Application/zip"; "Accept-Encoding" = "gzip, deflate"; "Content-Type" = "Application/zip;charset=utf-8"; } + + # --- Add the Authorization header + if ($Script:vROConnection.token) + { + $Headers.Add("Authorization", "Bearer $($Script:vROConnection.Token)") + } + else { + $Headers.Add("Authorization", "Basic $($Script:vROConnection.EncodedPassword)") + } + } process { diff --git a/src/Functions/Public/workflow-service/Export-vROWorkflowIcon.ps1 b/src/Functions/Public/workflow-service/Export-vROWorkflowIcon.ps1 index dd9c6f8..c59f5cb 100644 --- a/src/Functions/Public/workflow-service/Export-vROWorkflowIcon.ps1 +++ b/src/Functions/Public/workflow-service/Export-vROWorkflowIcon.ps1 @@ -52,7 +52,16 @@ $Headers = @{ "Content-Type" = "image/png"; - "Authorization" = "Basic $($Script:vROConnection.EncodedPassword)"; + + } + + # --- Add the Authorization header + if ($Script:vROConnection.token) + { + $Headers.Add("Authorization", "Bearer $($Script:vROConnection.Token)") + } + else { + $Headers.Add("Authorization", "Basic $($Script:vROConnection.EncodedPassword)") } # --- Run vRO REST Request diff --git a/src/Functions/Public/workflow-service/Export-vROWorkflowSchema.ps1 b/src/Functions/Public/workflow-service/Export-vROWorkflowSchema.ps1 index 18b282c..74419df 100644 --- a/src/Functions/Public/workflow-service/Export-vROWorkflowSchema.ps1 +++ b/src/Functions/Public/workflow-service/Export-vROWorkflowSchema.ps1 @@ -52,9 +52,18 @@ $Headers = @{ "Content-Type" = "image/png"; - "Authorization" = "Basic $($Script:vROConnection.EncodedPassword)"; + } + # --- Add the Authorization header + if ($Script:vROConnection.token) + { + $Headers.Add("Authorization", "Bearer $($Script:vROConnection.Token)") + } + else { + $Headers.Add("Authorization", "Basic $($Script:vROConnection.EncodedPassword)") + } + # --- Run vRO REST Request Invoke-vRORestMethod -Method GET -Headers $Headers -URI $URI -OutFile $File -Verbose:$VerbosePreference diff --git a/src/Functions/Public/workflow-service/Import-vROWorkflow.ps1 b/src/Functions/Public/workflow-service/Import-vROWorkflow.ps1 index 947dea1..614f7dd 100644 --- a/src/Functions/Public/workflow-service/Import-vROWorkflow.ps1 +++ b/src/Functions/Public/workflow-service/Import-vROWorkflow.ps1 @@ -98,12 +98,20 @@ $Headers = @{ - "Authorization" = "Basic $($Script:vROConnection.EncodedPassword)"; "Accept" = "Application/json" "Accept-Encoding" = "gzip,deflate,sdch"; "Content-Type" = "multipart/form-data; boundary=$($Boundary)" } + # --- Add the Authorization header + if ($Script:vROConnection.token) + { + $Headers.Add("Authorization", "Bearer $($Script:vROConnection.Token)") + } + else { + $Headers.Add("Authorization", "Basic $($Script:vROConnection.EncodedPassword)") + } + if ($PSCmdlet.ShouldProcess($FileInfo.FullName)){ # --- Run vRO REST Request