Skip to content

Auto access token refresh #278

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
Write-Output "There were $($errors.Count) errors and $($warnings.Count) warnings total."
}
- name: Upload test results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: pssa-results
path: ${{ github.workspace }}/pssa.json
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
*.Pester.Defaults.json
*.zip
.DS_Store
2 changes: 1 addition & 1 deletion RELEASE.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
- Fix invalid Id error, [#262](https://github.com/Snow-Shell/servicenow-powershell/issues/262)
- Add support for access token refresh, [#277](https://github.com/Snow-Shell/servicenow-powershell/issues/277)
2 changes: 1 addition & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ $params = @{
New-ServiceNowSession @params
```

Oauth authentication with user credential as well as application/client credential. The application/client credential can be found in the System OAuth->Application Registry section of ServiceNow.
Oauth authentication with user credential as well as application/client credential. The application/client credential can be found in the System OAuth->Application Registry section of ServiceNow. The access token will be refreshed automatically when it expires.
```PowerShell
$params = @{
Url = 'instance.service-now.com'
Expand Down
29 changes: 29 additions & 0 deletions ServiceNow/Private/Get-ServiceNowAuth.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,35 @@ function Get-ServiceNowAuth {

if ( $ServiceNowSession.Count -gt 0 ) {
$hashOut.Uri = $ServiceNowSession.BaseUri

# check if we need a new access token
if ( $ServiceNowSession.ExpiresOn -lt (Get-Date) -and $ServiceNowSession.RefreshToken -and $ServiceNowSession.ClientCredential ) {
# we've expired and have a refresh token
$refreshParams = @{
Uri = 'https://{0}/oauth_token.do' -f $ServiceNowSession.Domain
Method = 'POST'
ContentType = 'application/x-www-form-urlencoded'
Body = @{
grant_type = 'refresh_token'
client_id = $ServiceNowSession.ClientCredential.UserName
client_secret = $ServiceNowSession.ClientCredential.GetNetworkCredential().password
refresh_token = $ServiceNowSession.RefreshToken.GetNetworkCredential().password
}
}

$response = Invoke-RestMethod @refreshParams

$ServiceNowSession.AccessToken = New-Object System.Management.Automation.PSCredential('AccessToken', ($response.access_token | ConvertTo-SecureString -AsPlainText -Force))
$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
Expand Down
8 changes: 7 additions & 1 deletion ServiceNow/Public/New-ServiceNowSession.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ Create a new ServiceNow session
Create a new ServiceNow session via credentials, OAuth, or access token.
This session will be used by default for all future calls.
Optionally, you can specify the api version you'd like to use; the default is the latest.

To use OAuth, ensure you've set it up, https://docs.servicenow.com/bundle/quebec-platform-administration/page/administer/security/task/t_SettingUpOAuth.html.

If using OAuth, the client credential will be stored in the script scoped variable ServiceNowSession and the access token will be automatically refreshed.

.PARAMETER Url
Base domain for your ServiceNow instance, eg. tenant.domain.com

Expand Down Expand Up @@ -200,8 +203,11 @@ function New-ServiceNowSession {
if ($token.expires_in) {
$expiryTime = (Get-Date).AddSeconds($token.expires_in)
$newSession.Add('ExpiresOn', $expiryTime)
Write-Verbose "Token will expire at $expiryTime"
Write-Verbose "Access token will expire at $expiryTime"
}
# store client credential as it will be needed to refresh the access token
$newSession.Add('ClientCredential', $ClientCredential)

}
else {
# invoke-webrequest didn't throw an error, but we didn't get a token back either
Expand Down
4 changes: 2 additions & 2 deletions ServiceNow/ServiceNow.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
RootModule = 'ServiceNow.psm1'

# Version number of this module.
ModuleVersion = '4.0.5'
ModuleVersion = '4.1'

# Supported PSEditions
# CompatiblePSEditions = @()
Expand All @@ -27,7 +27,7 @@ Author = 'Greg Brownstein, Rick Arroues, Sam Martin'
CompanyName = 'None'

# Copyright statement for this module
Copyright = '(c) 2015-2023 Snow-Shell. All rights reserved.'
Copyright = '(c) 2015-2025 Snow-Shell. All rights reserved.'

# Description of the functionality provided by this module
Description = 'Automate against ServiceNow service and asset management. This module can be used standalone, with Azure Automation, or Docker.'
Expand Down