Private/Get-ServiceNowAuth.ps1
|
function Get-ServiceNowAuth { <# .SYNOPSIS Return hashtable with base Uri and auth info. Add uri leaf, body, etc to output. .DESCRIPTION .INPUTS None .OUTPUTS Hashtable #> [OutputType([Hashtable])] [CmdletBinding()] [System.Diagnostics.CodeAnalysis.SuppressMessage('PSAvoidUsingConvertToSecureStringWithPlainText', '', Justification = 'requirement of azure automation')] param ( [Parameter()] [Alias('N')] [string] $Namespace = 'now', [Parameter()] [Alias('S')] [hashtable] $ServiceNowSession ) begin { $hashOut = @{} } process { if ( $ServiceNowSession.Count -gt 0 ) { $hashOut.Uri = $ServiceNowSession.BaseUri + $Namespace if ($ServiceNowSession.Version) { $hashOut.uri = $hashOut.uri + $ServiceNowSession.Version } # check if we need a new access token if ( $ServiceNowSession.ExpiresOn -lt (Get-Date) -and $ServiceNowSession.ClientCredential ) { # Build refresh/re-auth body based on grant type $refreshBody = @{ client_id = $ServiceNowSession.ClientCredential.UserName client_secret = $ServiceNowSession.ClientCredential.GetNetworkCredential().password } if ($ServiceNowSession.GrantType -eq 'client_credentials') { # Client credentials: re-authenticate (no refresh token available) $refreshBody['grant_type'] = 'client_credentials' } elseif ($ServiceNowSession.RefreshToken) { # Password grant: use refresh token $refreshBody['grant_type'] = 'refresh_token' $refreshBody['refresh_token'] = $ServiceNowSession.RefreshToken.GetNetworkCredential().password } else { Write-Warning 'Access token expired but no refresh method available' } if ($refreshBody.ContainsKey('grant_type')) { $refreshParams = @{ Uri = 'https://{0}/oauth_token.do' -f $ServiceNowSession.Domain Method = 'POST' ContentType = 'application/x-www-form-urlencoded' Body = $refreshBody } $response = Invoke-RestMethod @refreshParams $ServiceNowSession.AccessToken = New-Object System.Management.Automation.PSCredential('AccessToken', ($response.access_token | ConvertTo-SecureString -AsPlainText -Force)) # Update refresh token if provided (password grant only) if ($response.refresh_token) { $ServiceNowSession.RefreshToken = New-Object System.Management.Automation.PSCredential('RefreshToken', ($response.refresh_token | ConvertTo-SecureString -AsPlainText -Force)) } if ($response.expires_in) { $ServiceNowSession.ExpiresOn = (Get-Date).AddSeconds($response.expires_in) Write-Verbose ('Access token has been refreshed and will expire at {0}' -f $ServiceNowSession.ExpiresOn) } # ensure script/module scoped variable is updated $script:ServiceNowSession = $ServiceNowSession } } if ( $ServiceNowSession.AccessToken ) { $hashOut.Headers = @{ 'Authorization' = 'Bearer {0}' -f $ServiceNowSession.AccessToken.GetNetworkCredential().password } } else { # issue 248 $pair = '{0}:{1}' -f $ServiceNowSession.Credential.UserName, $ServiceNowSession.Credential.GetNetworkCredential().Password $hashOut.Headers = @{ Authorization = 'Basic ' + [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($pair)) } } if ( $ServiceNowSession.Proxy ) { $hashOut.Proxy = $ServiceNowSession.Proxy if ( $ServiceNowSession.ProxyCredential ) { $hashOut.ProxyCredential = $ServiceNowSession.ProxyCredential } else { $hashOut.ProxyUseDefaultCredentials = $true } } # } elseif ( $Connection ) { # Write-Verbose 'connection' # # issue 248 # $pair = '{0}:{1}' -f $Connection.Username, $Connection.Password # $hashOut.Headers = @{ Authorization = 'Basic ' + [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($pair)) } # $hashOut.Uri = 'https://{0}/api/{1}/v1' -f $Connection.ServiceNowUri, $Namespace } elseif ( $env:SNOW_SERVER ) { $hashOut.Uri = 'https://{0}/api/{1}' -f $env:SNOW_SERVER, $Namespace if ( $env:SNOW_TOKEN ) { $hashOut.Headers = @{ 'Authorization' = 'Bearer {0}' -f $env:SNOW_TOKEN } } elseif ( $env:SNOW_USER -and $env:SNOW_PASS ) { $hashOut.Credential = New-Object System.Management.Automation.PSCredential($env:SNOW_USER, ($env:SNOW_PASS | ConvertTo-SecureString -AsPlainText -Force)) } else { throw 'A ServiceNow server environment variable has been set, but authentication via SNOW_TOKEN or SNOW_USER/SNOW_PASS was not found' } } else { throw "You must authenticate by calling the New-ServiceNowSession cmdlet" } } end { $hashOut.Clone() } } |