This commit is contained in:
Zack Meier
2026-04-15 15:45:50 -05:00
commit 1d304511b8
613 changed files with 140998 additions and 0 deletions
@@ -0,0 +1,95 @@
<#
.SYNOPSIS
A short one-line action-based description, e.g. 'Tests if a function is valid'
.DESCRIPTION
A longer description of the function, its purpose, common use cases, etc.
.NOTES
state values
-5 New
-4 Access
-2 Scheduled
-1 Implement
0 Review
3 Close
Close code
Close notes
.LINK
Specify a URI to a help page, this will show when Get-Help -Online is used.
.EXAMPLE
Test-MyTestFunction -Verbose
Explanation of the function or its result. You can include multiple examples with additional .EXAMPLE lines
#>
function Complete-ITDServiceNowChangeRequest {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[string]
$Number,
[string]
$CloseCode,
[string]
$CloseNotes
)
begin {
}
process {
try {
Write-Verbose -Message ($Number + " If state is Assess, do nothing")
$CHG = Get-ITDServiceNowRecord -ItemType 'Change Request' -Number $Number
If ($CHG.State.display_value -eq "Assess") {
Write-Error -Message ($Number + " is currently in Assess state. Unable to continue until the CHG is Approved.")
}
Else {
Write-Verbose -Message ($Number + " If state is New and Type is Standard, set to Schedule")
$CHG = Get-ITDServiceNowRecord -ItemType 'Change Request' -Number $Number
If ($CHG.State.display_value -eq "New" -and $CHG.type.display_value -eq 'Standard') {
Update-ITDServiceNowRecord -ItemType 'Change Request' -Number $Number -Values @{
state = 'Scheduled'
} | Out-Null
}
Write-Verbose -Message ($Number + " If state is Schedule, set to Implement")
$CHG = Get-ITDServiceNowRecord -ItemType 'Change Request' -Number $Number
If ($CHG.State.display_value -eq "Scheduled") {
Update-ITDServiceNowRecord -ItemType 'Change Request' -Number $Number -Values @{
state = 'Implement'
} | Out-Null
}
Write-Verbose -Message ($Number + " If state is Implement, set to Review")
$CHG = Get-ITDServiceNowRecord -ItemType 'Change Request' -Number $Number
If ($CHG.State.display_value -eq "Implement") {
Update-ITDServiceNowRecord -ItemType 'Change Request' -Number $Number -Values @{
state = 'Review';
} | Out-Null
}
Write-Verbose -Message ($Number + " If state is Review, set to Close")
$CHG = Get-ITDServiceNowRecord -ItemType 'Change Request' -Number $Number
If ($CHG.State.display_value -eq "Review") {
Update-ITDServiceNowRecord -ItemType 'Change Request' -Number $Number -Values @{
state = 'Closed';
close_code = $CloseCode;
close_notes = $CloseNotes;
} | Out-Null
}#>
}
}
catch {
Write-Error -Message $error[0]
}
}
end {
}
}
@@ -0,0 +1,49 @@
<#
.SYNOPSIS
A short one-line action-based description, e.g. 'Tests if a function is valid'
.DESCRIPTION
A longer description of the function, its purpose, common use cases, etc.
.NOTES
Information or caveats about the function e.g. 'This function is not supported in Linux'
.LINK
Specify a URI to a help page, this will show when Get-Help -Online is used.
.EXAMPLE
Test-MyTestFunction -Verbose
Explanation of the function or its result. You can include multiple examples with additional .EXAMPLE lines
#>
function Get-ITDServiceNowChangeTemplateStandard {
[CmdletBinding()]
param (
[string]
$Name
)
begin {
}
process {
If($PSBoundParameters.ContainsKey('Name')){
$InvokeRestMethodParams = @{
Method = 'Get';
Uri = ($Script:ServiceNowSession.Uri + "/api/sn_chg_rest/change/standard/template?sysparm_query=active=true^name=$Name");
Headers = $Script:ServiceNowSession.Headers;
ContentType = $Script:ServiceNowSession.ContentType;
}
} Else {
$InvokeRestMethodParams = @{
Method = 'Get';
Uri = ($Script:ServiceNowSession.Uri + "/api/sn_chg_rest/change/standard/template?sysparm_query=active=true");
Headers = $Script:ServiceNowSession.Headers;
ContentType = $Script:ServiceNowSession.ContentType;
}
}
$InvokeResult = (Invoke-RestMethod @InvokeRestMethodParams).result
}
end {
Write-Output $InvokeResult
}
}
@@ -0,0 +1,281 @@
<#
.SYNOPSIS
Retrieve ServiceNow records based on the provided parameters.
.DESCRIPTION
Retrieve ServiceNow records based on the provided parameters. Use the ItemType parameter for frequently used tables.
If the ItemType is not listed, then use the Table parameter to specify the ServiceNow table you wish to query.
.PARAMETER ItemType
The type of item to retrieve. Valid values are 'Incident', 'Change Request', 'Catalog Task', and 'Request Item'.
.PARAMETER Table
The name of the ServiceNow table to query if the ItemType is not listed.
.PARAMETER SysId
The SysId of the record to retrieve.
.PARAMETER Number
The number of the record to retrieve.
.PARAMETER Filter
A filter to apply to the query.
.PARAMETER Limit
The maximum number of records to retrieve. Must be a positive integer.
.PARAMETER Fields
An array of fields to include in the results.
.PARAMETER IncludeCustomVariable
A switch to include custom variables in the results.
.PARAMETER IncludeVariableSet
A switch to include variable sets in the results.
.EXAMPLE
Get-ITDServiceNowRecord -ItemType 'Incident' -Number 'INC0012345'
This example retrieves the incident record with the specified number.
.EXAMPLE
Get-ITDServiceNowRecord -Table 'cmdb_ci_win_server' -Filter 'active=true' -Limit 10
This example retrieves up to 10 active Windows server records from the specified table.
.LINK
https://developer.servicenow.com/
#>
function Get-ITDServiceNowRecord {
[CmdletBinding(SupportsPaging)]
param (
[Parameter(ParameterSetName = 'ItemType')]
[ValidateSet('Incident', 'Change Request', 'Catalog Task', 'Request Item')]
[string]
$ItemType,
[Parameter(ParameterSetName = 'Table')]
[string]
$Table,
[string]
$SysId,
[string]
$Number,
[string]
$Filter,
[ValidateRange(1, [int]::MaxValue)]
[int]
$Limit,
[string[]]
$Fields,
[switch]
$IncludeCustomVariable,
[switch]
$IncludeVariableSet
)
begin {
}
process {
switch ($PSCmdlet.ParameterSetName) {
'ItemType' {
$Table = Get-ITDServiceNowTable -ItemType $ItemType
}
'Table' {
# examples: 'cmdb_ci_win_server', 'cmdb_ci_ip_network', 'cmdb_ci_service_auto', 'sc_item_option_mtom'
# don't do anything
}
}
$Uri = ($Script:ServiceNowSession.Uri + "/api/now/table/" + $Table )
$Body = @{}
$sysparm_query = @()
switch ($PSBoundParameters.Keys) {
SysId {
$sysparm_query += "sys_id=$SysId"
}
Number {
$sysparm_query += "number=$Number"
}
Filter {
$sysparm_query += $Filter
}
Fields {
$sysparm_fields = $Fields -join ','
}
}
If ($PSCmdlet.PagingParameters.IncludeTotalCount) {
}
Else {
If ($PSBoundParameters.ContainsKey('Limit')) {
$sysparm_limit = $Limit
}
Else {
Write-Verbose "Limited to 10 records returned unless specified with Limit parameter"
$sysparm_limit = 10;
}
}
Write-Verbose $uri
$Body = @{
sysparm_limit = $sysparm_limit;
sysparm_query = $sysparm_query -join '^';
sysparm_display_value = 'all';
sysparm_fields = $sysparm_fields;
}
$InvokeRestMethodParams = @{
Method = 'Get';
Uri = $Uri
Headers = $Script:ServiceNowSession.Headers;
ContentType = $Script:ServiceNowSession.ContentType;
Body = $Body;
}
Write-Verbose -Message ($Body.sysparm_query)
try {
$Result = (Invoke-RestMethod @InvokeRestMethodParams).Result
}
catch [System.UriFormatException] {
Write-Error "Invalid URI session. Did you run New-ITDServiceNowSession before execution?"
}
If ($IncludeCustomVariable) {
ForEach ($Record in $Result) {
$RecordSysId = $Record.sys_id
<#
$CustomFieldsParams = @{
Method = 'Get';
Uri = ($Script:ServiceNowSession.Uri + "/api/now/table/sc_item_option_mtom?request_item=" + $Record.Sys_id)
Headers = $Script:ServiceNowSession.Headers;
ContentType = $Script:ServiceNowSession.ContentType;
}
$CustomFieldsLookup = (Invoke-RestMethod @CustomFieldsParams).result
$sc_item_options = ForEach ($CustomField in $CustomFieldsLookup) {
#$scitemsysid = $sc_item_option.sc_item_option.value
$params = @{
Method = 'Get';
Uri = ($Script:ServiceNowSession.Uri + "/api/now/table/sc_item_option?sys_id=" + $CustomField.sc_item_option.value ); #+ "&sysparm_limit=100"
Headers = ($Script:ServiceNowSession.Headers);
ContentType = "application/json"
}
(Invoke-RestMethod @params).result
}
$MyArrayList = [System.Collections.ArrayList]@()
ForEach ($sc_item_option in $sc_item_options) {
$params = @{
Method = 'Get';
Uri = ($Script:ServiceNowSession.Uri + "/api/now/table/item_option_new?sys_id=" + $sc_item_option.item_option_new.value);
Headers = ($Script:ServiceNowSession.Headers);
ContentType = "application/json"
}
$vars = (Invoke-RestMethod @params).result
$obj = [PSCustomObject]@{
#sc_item_option_sysid = $sc_item_option.sys_id
#item_option_new_sysid = $vars.sys_id
name = $vars.name
question_text = $vars.question_text
value = $sc_item_option.value
type = $vars.type
# YES_NO = 1; MULTI_LINE_TEXT = 2; MULTIPLE_CHOICE = 3; NUMERIC_SCALE = 4; SELECT_BOX = 5; SINGLE_LINE_TEXT = 6; CHECKBOX = 7; REFERENCE = 8; DATE = 9; DATE_TIME = 10; LABEL = 11; BREAK = 12; MACRO = 14; UI_PAGE = 15; WIDE_SINGLE_LINE_TEXT = 16; MACRO_WITH_LABEL = 17; LOOKUP_SELECT_BOX = 18; CONTAINER_START = 19; CONTAINER_END = 20; LIST_COLLECTOR = 21; LOOKUP_MULTIPLE_CHOICE = 22; HTML = 23; SPLIT = 24; MASKED = 25;
}
$null = $MyArrayList.Add($obj)
}
$Record | Add-Member @{'CustomFields' = $MyArrayList }
$Record
}#>
$Record | Add-Member @{
'CustomVariable' = [pscustomobject]@{}
}
$InvokeRestMethodParams = @{
Method = 'Get';
Uri = ($Script:ServiceNowSession.Uri + "/api/now/table/sc_item_option_mtom");
ContentType = ($Script:ServiceNowSession.ContentType);
Headers = ($Script:ServiceNowSession.Headers);
Body = @{
request_item = $Record.sys_id.value;
sysparm_fields = (@('sc_item_option.item_option_new.name',
'sc_item_option.value',
'sc_item_option.item_option_new.type',
'sc_item_option.item_option_new.question_text',
'sc_item_option.item_option_new.reference') -join ',');
#sysparm_query = "sc_item_option.item_option_new.typeIN1,2,3,4,5,6,7,8,9,10,16,18,21,22,26"
# YES_NO = 1; MULTI_LINE_TEXT = 2; MULTIPLE_CHOICE = 3; NUMERIC_SCALE = 4; SELECT_BOX = 5; SINGLE_LINE_TEXT = 6; CHECKBOX = 7; REFERENCE = 8; DATE = 9; DATE_TIME = 10; LABEL = 11; BREAK = 12; MACRO = 14; UI_PAGE = 15; WIDE_SINGLE_LINE_TEXT = 16; MACRO_WITH_LABEL = 17; LOOKUP_SELECT_BOX = 18; CONTAINER_START = 19; CONTAINER_END = 20; LIST_COLLECTOR = 21; LOOKUP_MULTIPLE_CHOICE = 22; HTML = 23; SPLIT = 24; MASKED = 25;
};
}
$customVars = (Invoke-RestMethod @InvokeRestMethodParams).result #-ov c
ForEach ($var in $customVars) {
$newVar = [pscustomobject] @{
Value = $var.'sc_item_option.value'
DisplayName = $var.'sc_item_option.item_option_new.question_text'
Type = $var.'sc_item_option.item_option_new.type'
}
# show the underlying value if the option is a reference type
<#if ($newVar.Type -eq 'Reference' ) {
$newVar.Value = (Get-ServiceNowRecord -Table $var.'sc_item_option.item_option_new.reference' -ID $var.'sc_item_option.value' -Property name -AsValue -ServiceNowSession $ServiceNowSession)
#>
$Record.CustomVariable | Add-Member @{ $var.'sc_item_option.item_option_new.name' = $newVar }
}
}
}
else {
}
If ($IncludeVariableSet) {
ForEach ($Record in $Result) {
$InvokeRestMethodParams = @{
Method = 'Get';
Uri = ($Script:ServiceNowSession.Uri + "/api/now/table/sc_multi_row_question_answer?parent_id=" + $Record.sys_id.value);
ContentType = ($Script:ServiceNowSession.ContentType);
Headers = ($Script:ServiceNowSession.Headers);
}
$AllRows = (Invoke-RestMethod @InvokeRestMethodParams).result
$Row_Indexes = ($AllRows | Select-Object -Unique row_index).row_index
$ArrayList = [System.Collections.ArrayList]@()
ForEach ($Row in $Row_Indexes) {
$obj = [PSCustomObject]@{}
$RowProperties = $AllRows | Where-Object row_index -EQ $Row
$RowProperties | ForEach-Object -ThrottleLimit 10 -Parallel {
Write-Verbose -Message ("Property start " + ($USING:Script:ServiceNowSession.Uri + "/api/now/table/item_option_new?sys_id=" + $_.item_option_new.value) )
$params = @{
Method = 'Get';
Uri = ($USING:Script:ServiceNowSession.Uri + "/api/now/table/item_option_new?sys_id=" + $_.item_option_new.value);
ContentType = ($USING:Script:ServiceNowSession.ContentType);
Headers = ($USING:Script:ServiceNowSession.Headers);
MaximumRetryCount = 10;
RetryIntervalSec = 5;
}
$vars = (Invoke-RestMethod @params).result
$USING:obj | Add-Member -MemberType NoteProperty -Name $vars.name -Value $_.value
}
$null = $ArrayList.Add($obj)
}
$Record | Add-Member @{
'VariableSet' = $ArrayList
}
}
}
Write-Output $Result
}
end {
}
}
@@ -0,0 +1,32 @@
<#
.SYNOPSIS
A short one-line action-based description, e.g. 'Tests if a function is valid'
.DESCRIPTION
A longer description of the function, its purpose, common use cases, etc.
.NOTES
Information or caveats about the function e.g. 'This function is not supported in Linux'
.LINK
Specify a URI to a help page, this will show when Get-Help -Online is used.
.EXAMPLE
Test-MyTestFunction -Verbose
Explanation of the function or its result. You can include multiple examples with additional .EXAMPLE lines
#>
function Get-ITDServiceNowSession {
[CmdletBinding()]
param (
)
begin {
}
process {
}
end {
Write-Output $Script:ServiceNowSession
}
}
@@ -0,0 +1,56 @@
<#
.SYNOPSIS
A short one-line action-based description, e.g. 'Tests if a function is valid'
.DESCRIPTION
A longer description of the function, its purpose, common use cases, etc.
.NOTES
Information or caveats about the function e.g. 'This function is not supported in Linux'
.LINK
Specify a URI to a help page, this will show when Get-Help -Online is used.
.EXAMPLE
Test-MyTestFunction -Verbose
Explanation of the function or its result. You can include multiple examples with additional .EXAMPLE lines
#>
function Get-ITDServiceNowTable {
[CmdletBinding()]
param (
[string]
$ItemType
)
begin {
}
process {
switch ($ItemType) {
'Incident' {
$Table = 'incident'
}
'Change Request' {
$Table = 'change_request'
}
'Request' {
$Table = 'sc_request'
}
'Request Item' {
$Table = 'sc_req_item'
}
'Catalog Task' {
$Table = 'sc_task'
}
'cmdb_ci_server_list' {
$Table = 'cmdb_ci_server_list'
}
'cmdb_ci_win_server' {
$Table = 'cmdb_ci_win_server'
}
}
}
end {
Write-Verbose $Table
Write-Output $Table
}
}
@@ -0,0 +1,56 @@
<#
.SYNOPSIS
A short one-line action-based description, e.g. 'Tests if a function is valid'
.DESCRIPTION
A longer description of the function, its purpose, common use cases, etc.
.NOTES
Information or caveats about the function e.g. 'This function is not supported in Linux'
.LINK
Specify a URI to a help page, this will show when Get-Help -Online is used.
.EXAMPLE
Test-MyTestFunction -Verbose
Explanation of the function or its result. You can include multiple examples with additional .EXAMPLE lines
#>
function Get-ITDServiceNowUser {
[CmdletBinding()]
param (
[Parameter(ParameterSetName = 'Email')]
[string]
$Email,
[Parameter(ParameterSetName = 'Username')]
[string]
$Username,
[Parameter(ParameterSetName = 'SysId')]
[string]
$SysId
)
begin {
}
process {
$Query = "?sysparm_query="
If ($Email) { $Query += "email=$Email" }
If ($UserName) { $Query += "user_name=$Username" }
If ($SysId) { $Query += "sys_id=$SysId" }
$InvokeRestMethodParams = @{
Method = 'Get';
Uri = ($Script:ServiceNowSession.Uri + "/api/now/table/sys_user" + $Query + "&sysparm_limit=10");
Headers = $Script:ServiceNowSession.Headers;
ContentType = $Script:ServiceNowSession.ContentType;
}
Write-Verbose $InvokeRestMethodParams.Uri
$Result = Invoke-RestMethod @InvokeRestMethodParams
}
end {
Write-Output $Result.result
}
}
@@ -0,0 +1,48 @@
<#
.SYNOPSIS
A short one-line action-based description, e.g. 'Tests if a function is valid'
.DESCRIPTION
A longer description of the function, its purpose, common use cases, etc.
.NOTES
Information or caveats about the function e.g. 'This function is not supported in Linux'
.LINK
Specify a URI to a help page, this will show when Get-Help -Online is used.
.EXAMPLE
Test-MyTestFunction -Verbose
Explanation of the function or its result. You can include multiple examples with additional .EXAMPLE lines
#>
function Get-ITDServiceNowUserGroup {
[CmdletBinding()]
param (
[string]
$Name
)
begin {
}
process {
# Invoke-RestMethod -Method GET -Uri ($Url + "api/now/table/sys_user_group?name=NDIT-Computer Systems&sysparm_limit=1") -Credential $SNowVMCred -Headers $SnowSessionHeader -ContentType $Type -ov x
$Query = "?sysparm_query="
If ($Name) { $Query += "name=$Name" }
$InvokeRestMethodParams = @{
Method = 'Get';
Uri = ($Script:ServiceNowSession.Uri + "/api/now/table/sys_user_group" + $Query + "&sysparm_limit=10");
Headers = $Script:ServiceNowSession.Headers;
ContentType = $Script:ServiceNowSession.ContentType;
}
Write-Verbose $InvokeRestMethodParams.Uri
$Result = Invoke-RestMethod @InvokeRestMethodParams
}
end {
Write-Output $Result.result
}
}
@@ -0,0 +1,246 @@
<#
.SYNOPSIS
A short one-line action-based description, e.g. 'Tests if a function is valid'
.DESCRIPTION
A longer description of the function, its purpose, common use cases, etc.
.NOTES
$StartTime & $EndTime
Send local time in parameter as [datetime] object
Function will convert the date object to UTC, and convert that result to a string via .ToString()
API properties of start_date and end_date require datetime formatted as string
(Get-Date -AsUTC).ToString('yyyy-MM-dd HH:mm:ss')
.LINK
Specify a URI to a help page, this will show when Get-Help -Online is used.
.EXAMPLE
$NewITDServiceNowChangeRequestParams = @{
TemplateName = 'NDIT-SPS-Server Add/Chg/Del'
RequestedByUsername = 'zmeier';
Category = 'Systems Platforms - Systems';
Subcategory = 'Windows';
Impact = 3;
ShortDescription = "things and stuff 5";
Description = "things and stuff description";
Justification = "things are being done to stuff";
Implementation = "do things to stuff";
RiskImpactAnalysis = "things will have stuff done to them";
BackoutPlan = "can't remove things from stuff"
TestPlan = "test stuff first"
WhoIsImpacted = "all the things";
StartTime = (Get-Date)
EndTime = (Get-Date).AddHours(1);
AssignmentGroup = 'NDIT-Computer Systems Windows';
ChangeManagerUsername = 'khellman';
ChangeCoordinatorUsername = 'gpgolberg';
AssignedToUsername = 'zmeier';
CabRequred = $false;
}
$CHG = New-ITDServiceNowChangeRequest @NewITDServiceNowChangeRequestParams
#>
function New-ITDServiceNowChangeRequest {
[CmdletBinding()]
param (
[Parameter(ParameterSetName = 'Standard')]
[string]
$TemplateName,
[string]
$RequestedByUsername,
[Parameter(Mandatory = $true)]
[string]
$Category,
[string]
$ConfigurationItemSysId,
[string]
$Subcategory,
[Parameter(Mandatory = $true)]
[string]
$ShortDescription,
[Parameter(Mandatory = $true)]
[string]
$Description,
[ValidateRange(1, 3)]
[int]
$Priority,
[ValidateRange(1, 3)]
[int]
$Impact,
[Parameter(Mandatory = $true)]
[string]
$Justification,
[Parameter(Mandatory = $true)]
[string]
$Implementation,
[Parameter(Mandatory = $true)]
[string]
$RiskImpactAnalysis,
[Parameter(Mandatory = $true)]
[string]
$BackoutPlan,
[Parameter(Mandatory = $true)]
[string]
$TestPlan,
[string]
$WhoIsImpacted,
[Parameter(Mandatory = $true)]
[string]
$ChangeManagerUsername,
[string]
$ChangeCoordinatorUsername,
[Parameter(Mandatory = $true)]
[string]
$AssignmentGroup,
[string]
$AssignedToUsername,
[Parameter(Mandatory = $true)]
[datetime]
$StartTime,
[Parameter(Mandatory = $true)]
[datetime]
$EndTime
<#
[ValidateSet($true,$false)]
[string]
$CabRequired = $true
#>
)
begin {
switch ($PSCmdlet.ParameterSetName) {
'Standard' {
Write-Verbose -Message "Standard Change Template parameter: $TemplateName" # Server Add/Chg/Del
# get standard template
$ChgTemplateStd = Get-ITDServiceNowChangeTemplateStandard -Name $TemplateName
$ChgTemplateStdSysId = $ChgTemplateStd.sys_id.value
}
Default {
}
}
}
process {
[PSCustomObject]$NewRecord = @{
category = $Category;
u_subcategory = $Subcategory
impact = $Impact;
urgency = $Urgency;
short_description = $ShortDescription;
description = $Description;
justification = $Justification;
implementation_plan = $Implementation;
risk_impact_analysis = $RiskImpactAnalysis;
backout_plan = $BackoutPlan;
test_plan = $TestPlan
u_who_is_impacted = $WhoIsImpacted;
start_date = (Get-Date -Date $StartTime -AsUTC).ToString('yyyy-MM-dd HH:mm:ss')
end_date = (Get-Date -Date $EndTime -AsUTC).ToString('yyyy-MM-dd HH:mm:ss')
}
If($ConfigurationItemSysId) {
$NewRecord += @{cmdb_ci = $ConfigurationItemSysId}
}
If ($CabRequired){
$NewRecord += @{cab_required = $true}
} Else {
$NewRecord += @{cab_required = $false}
}
If ($RequestedByUsername) {
$ReqBy = Get-ITDServiceNowUser -Username $RequestedByUsername
If (@($ReqBy).count -gt 1) {
Write-Error "Multiple requested users found, creation failed." -ErrorAction Stop
}
Else {
$NewRecord += @{requested_by = $ReqBy.sys_id }
}
}
If ($AssignmentGroup) {
$AssGroup = Get-ITDServiceNowUserGroup -Name $AssignmentGroup
If (@($AssGroup).count -gt 1) {
Write-Error "Multiple assignment groups found, creation failed." -ErrorAction Stop
}
Else {
$NewRecord += @{assignment_group = $AssGroup.sys_id }
}
}
$ChgManagerUsername = Get-ITDServiceNowUser -Username $ChangeManagerUsername
If (@($ChgManagerUsername).count -gt 1) {
Write-Error "Multiple users found for ChangeManagerUsername, creation failed." -ErrorAction Stop
}
Else {
$NewRecord += @{u_change_manager = $ChgManagerUsername.sys_id }
}
$ChgCoordUsername = Get-ITDServiceNowUser -Username $ChangeCoordinatorUsername
If (@($ChgCoordUsername).count -gt 1) {
Write-Error "Multiple users found for ChangeCoordinator, creation failed." -ErrorAction Stop
}
Else {
$NewRecord += @{u_change_coordinator = $ChgCoordUsername.sys_id }
}
If ($AssignedToUsername) {
$AssTo = Get-ITDServiceNowUser -Username $AssignedToUsername
If (@($AssTo).count -gt 1) {
Write-Error "Multiple assignment users found, incident creation failed." -ErrorAction Step
}
Else {
$NewRecord += @{assigned_to = $AssTo.sys_id }
}
}
Write-Verbose ($NewRecord | ConvertTo-Json)
switch ($PSCmdlet.ParameterSetName) {
'Standard' {
$Uri = ($Script:ServiceNowSession.Uri + "/api/sn_chg_rest/change/standard/$ChgTemplateStdSysId" );
}
Default {
Write-Verbose -Message ("Uri = " + $Uri)
$Uri = ($Script:ServiceNowSession.Uri + "/api/now/table/change_request");
}
}
Write-Verbose -Message "Standard CHG Template SysId = $Uri"
$InvokeRestMethodParams = @{
Method = 'Post';
Uri = $Uri;
Body = $NewRecord | ConvertTo-Json;
Headers = $Script:ServiceNowSession.Headers;
ContentType = "application/json"
}
#Write-Output $InvokeRestMethodParams
$result = (Invoke-RestMethod @InvokeRestMethodParams).result
}
end {
Write-Output $result
}
}
@@ -0,0 +1,202 @@
<#
.SYNOPSIS
A short one-line action-based description, e.g. 'Tests if a function is valid'
.DESCRIPTION
A longer description of the function, its purpose, common use cases, etc.
.NOTES
$StartTime & $EndTime
Send local time in parameter as [datetime] object
Function will convert the date object to UTC, and convert that result to a string via .ToString()
API properties of start_date and end_date require datetime formatted as string
.LINK
Specify a URI to a help page, this will show when Get-Help -Online is used.
.EXAMPLE
Test-MyTestFunction -Verbose
Explanation of the function or its result. You can include multiple examples with additional .EXAMPLE lines
#>
function New-ITDServiceNowChangeRequestOG {
[CmdletBinding()]
param (
[string]
$RequestedByUsername,
[Parameter(Mandatory = $true)]
[string]
$Category,
[string]
$Subcategory,
[Parameter(Mandatory = $true)]
[string]
$ShortDescription,
[Parameter(Mandatory = $true)]
[string]
$Description,
[ValidateRange(1, 3)]
[int]
$Priority,
[ValidateRange(1, 3)]
[int]
$Impact,
[Parameter(Mandatory = $true)]
[string]
$Justification,
[Parameter(Mandatory = $true)]
[string]
$Implementation,
[Parameter(Mandatory = $true)]
[string]
$RiskImpactAnalysis,
[Parameter(Mandatory = $true)]
[string]
$BackoutPlan,
[Parameter(Mandatory = $true)]
[string]
$TestPlan,
[Parameter(Mandatory = $true)]
[string]
$WhoIsImpacted,
[Parameter(Mandatory = $true)]
[string]
$ChangeManagerUsername,
[string]
$ChangeCoordinatorUsername,
[Parameter(Mandatory = $true)]
[string]
$AssignmentGroup,
[string]
$AssignedToUsername,
[Parameter(Mandatory = $true)]
[datetime]
$StartTime,
[Parameter(Mandatory = $true)]
[datetime]
$EndTime
)
begin {
}
process {
<#payload = {
"category": category,
"u_subcategory": subCategory,
"u_change_manager": chngMngrID,
"assigned_to": userID,
"u_change_coordinator": chngCoordID,
"assignment_group": grpID,
"short_description": shortDesc,
"description": desc,
"justification": justDesc,
"implementation_plan": implmntPlan,
"risk_impact_analysis": riskImpact,
"backout_plan": backoutPlan,
"test_plan": testPlan,
"start_date": sTime,
"end_date": eTime,
"cab_required": False,
}#>
[PSCustomObject]$NewRecord = @{
category = $Category;
u_subcategory = $Subcategory
impact = $Impact;
urgency = $Urgency;
short_description = $ShortDescription;
description = $Description;
justification = $Justification;
implementation_plan = $Implementation;
risk_impact_analysis = $RiskImpactAnalysis;
backout_plan = $BackoutPlan;
test_plan = $TestPlan
u_who_is_impacted = $WhoIsImpacted;
start_date = $StartTime.ToUniversalTime().ToString(); # see help/notes
end_date = $EndTime.ToUniversalTime().ToString(); # see help/notes
}
If ($RequestedBy) {
$ReqBy = Get-ITDServiceNowUser -Username $RequestedBy
If (@($ReqBy).count -gt 1) {
Write-Error "Multiple requested users found, incident creation failed." -ErrorAction Stop
}
Else {
$NewRecord += @{requested_by = $ReqBy.sys_id }
}
}
If ($AssignmentGroup) {
$AssGroup = Get-ITDServiceNowUserGroup -Name $AssignmentGroup
If (@($AssGroup).count -gt 1) {
Write-Error "Multiple assignment groups found, incident creation failed." -ErrorAction Stop
}
Else {
$NewRecord += @{assignment_group = $AssGroup.sys_id }
}
}
$ChgManagerUsername = Get-ITDServiceNowUser -Username $ChangeManagerUsername
If (@($ChgManagerUsername).count -gt 1) {
Write-Error "Multiple users found for ChangeManagerUsername, incident creation failed." -ErrorAction Stop
}
Else {
$NewRecord += @{u_change_manager = $ChgManagerUsername.sys_id }
}
$ChgCoordUsername = Get-ITDServiceNowUser -Username $ChangeCoordinatorUsername
If (@($ChgCoordUsername).count -gt 1) {
Write-Error "Multiple users found for ChangeManagerUsername, incident creation failed." -ErrorAction Stop
}
Else {
$NewRecord += @{u_change_coordinator = $ChgCoordUsername.sys_id }
}
If ($AssignedToUsername) {
$AssTo = Get-ITDServiceNowUser -UserName $AssignedToUsername
If (@($AssTo).count -gt 1) {
Write-Error "Multiple assignment users found, incident creation failed." -ErrorAction Step
}
Else {
$NewRecord += @{assigned_to = $AssTo.sys_id }
}
}
Write-Verbose ($NewRecord | ConvertTo-Json)
$InvokeRestMethodParams = @{
Method = 'Post';
Uri = ($Script:ServiceNowSession.Uri + "/api/now/table/change_request");
Body = $NewRecord | ConvertTo-Json;
Headers = $Script:ServiceNowSession.Headers;
ContentType = "application/json"
}
#Write-Output $InvokeRestMethodParams
$result = Invoke-RestMethod @InvokeRestMethodParams
}
end {
Write-Output $result
}
}
@@ -0,0 +1,120 @@
<#
.SYNOPSIS
Creates a new incident in ServiceNow.
.DESCRIPTION
This function creates a new incident in ServiceNow using the provided parameters. It requires either the caller's username or email, along with a short description and a detailed description of the incident.
.PARAMETER CallerUsername
The username of the caller reporting the incident. This parameter is mandatory if CallerEmail is not provided.
.PARAMETER CallerEmail
The email address of the caller reporting the incident. This parameter is mandatory if CallerUsername is not provided.
.PARAMETER ShortDescription
A brief summary of the incident.
.PARAMETER Description
A detailed description of the incident.
.PARAMETER Impact
The impact level of the incident. Valid values are 1 (High), 2 (Medium), and 3 (Low). Default is 3.
.PARAMETER Urgency
The urgency level of the incident. Valid values are 1 (High), 2 (Medium), and 3 (Low). Default is 3.
.PARAMETER Category
The category of the incident.
.EXAMPLE
New-ITDServiceNowIncident -CallerUsername 'jdoe' -ShortDescription 'System outage' -Description 'The system is down and not responding.' -Impact 1 -Urgency 1 -Category 'Network'
This example creates a new high-impact, high-urgency incident for a system outage reported by the user 'jdoe'.
#>
function New-ITDServiceNowIncident {
[CmdletBinding()]
param (
[Parameter(ParameterSetName = 'CallerUsername', Mandatory = $true)]
[string]
$CallerUsername,
[Parameter(ParameterSetName = 'CallerEmail', Mandatory = $true)]
[string]
$CallerEmail,
[Parameter(Mandatory = $true)]
[string]
$ShortDescription,
[Parameter(Mandatory = $true)]
[string]
$Description,
[ValidateRange(1, 3)]
[int]
$Impact = 3,
[ValidateRange(1, 3)]
[int]
$Urgency = 3,
[string]
$Category,
[string]
$Subcategory,
[string]
$AssignmentGroup,
[string]
$AssignedTo
)
begin {
}
process {
# determine caller id
switch ($PSCmdlet.ParameterSetName) {
'CallerUsername' {
$Caller = Get-ITDServiceNowUser -Username $CallerUsername
}
'CallerEmail' {
$Caller = Get-ITDServiceNowUser -Email $CallerEmail
}
}
If (@($Caller).count -gt 1) {
Write-Error "Multiple users found, incident creation failed." -ErrorAction Stop
}
[PSCustomObject]$NewRecord = @{
caller_id = $Caller.sys_id
short_description = $ShortDescription;
description = $Description;
impact = $Impact;
urgency = $Urgency;
category = $Category;
subcategory = $Subcategory
}
If ($AssignmentGroup) {
$AssGroup = Get-ITDServiceNowUserGroup -Name $AssignmentGroup
If (@($AssGroup).count -gt 1) {
Write-Error "Multiple assignment groups found, incident creation failed." -ErrorAction Step
}
Else {
$NewRecord += @{assignment_group = $AssGroup.sys_id }
}
}
$InvokeRestMethodParams = @{
Method = 'Post';
Uri = ($Script:ServiceNowSession.Uri + "/api/now/table/incident");
Body = $NewRecord | ConvertTo-Json;
Headers = $Script:ServiceNowSession.Headers;
ContentType = "application/json"
}
#Write-Output $InvokeRestMethodParams
$result = Invoke-RestMethod @InvokeRestMethodParams
}
end {
$result #| select number, impact, urgency, assignment_group, short_description
}
}
@@ -0,0 +1,41 @@
<#
.SYNOPSIS
Creates a new record in a specified ServiceNow table.
.DESCRIPTION
This function creates a new record in the specified ServiceNow table using the provided values.
.PARAMETER Table
The name of the ServiceNow table where the new record will be created.
.PARAMETER Values
A hashtable containing the field names and values for the new record.
.EXAMPLE
$values = @{
short_description = 'New incident';
description = 'Detailed description of the incident';
impact = 3;
urgency = 3;
}
New-ITDServiceNowRecord -Table 'incident' -Values $values
This example creates a new incident record in the ServiceNow 'incident' table with the specified values.
.NOTES
Ensure that the ServiceNow session is correctly initialized before calling this function.
#>
function New-ITDServiceNowRecord {
param(
[string]
$Table,
[hashtable]
$Values
)
$InvokeRestMethodParams = @{
Method = 'Post';
Uri = ($Script:ServiceNowSession.Uri + "/api/now/table/$Table");
Body = $Values | ConvertTo-Json;
Headers = $Script:ServiceNowSession.Headers;
ContentType = "application/json"
}
#Write-Output $InvokeRestMethodParams
$result = Invoke-RestMethod @InvokeRestMethodParams
}
@@ -0,0 +1,116 @@
<#
.SYNOPSIS
A short one-line action-based description, e.g. 'Tests if a function is valid'
.DESCRIPTION
A longer description of the function, its purpose, common use cases, etc.
.NOTES
Information or caveats about the function e.g. 'This function is not supported in Linux'
.LINK
Specify a URI to a help page, this will show when Get-Help -Online is used.
.EXAMPLE
Test-MyTestFunction -Verbose
Explanation of the function or its result. You can include multiple examples with additional .EXAMPLE lines
#>
function New-ITDServiceNowServiceCatalogRequest {
[CmdletBinding()]
param (
[string]
$CategoryItemName,
[string]
$RequestedForEmail,
[hashtable]
$Values
)
begin {
}
process {
Write-Verbose -Message "Retrieve Category Item information"
$InvokeRestMethodParams = @{
Method = 'Get';
Uri = ($Script:ServiceNowSession.Uri + "/api/sn_sc/servicecatalog/items?sysparm_limit=5000");
Headers = $Script:ServiceNowSession.Headers;
ContentType = $Script:ServiceNowSession.ContentType;
}
$CategoryAllItems = (Invoke-RestMethod @InvokeRestMethodParams).result
$CategoryItem = $CategoryAllItems | Where-Object Name -EQ $CategoryItemName
$CategoryItemSysId = $CategoryItem.sys_id
Write-Verbose -Message "Retrieve RequestedBy and manager information"
$RequestedForSNUser = Get-ITDServiceNowUser -Email $RequestedForEmail
$RequiredVariables = @{
# Requester Information
v_requested_for = $RequestedForSNUser.sys_id;
v_requested_by = $RequestedForSNUser.sys_id;
v_user_email = $RequestedForSNUser.email;
v_user_phone = $RequestedForSNUser.phone;
v_alt_contact = "";
# Approval Information
v_approval_department = "f3c65cef1bfed050bba0113fad4bcb1d"; # Information Technology Dept
v_approval_department_code = "112.0";
v_approval_division = "f40758231b321450bba0113fad4bcb2d"; # Computer Systems
###v_approval_division_code = "32";
###v_approval_charge_code = "";
v_manager = $RequestedForSNUser.manager.value;
v_user_in_servicenow = "Yes";
# unknown
###requester_information = "true";
###v_container_requested_for = "true";
###v_user_in_servicenow = "Yes";
###v_container_requested_by = "true";
###approval_information = "true";
###request_commnets = "true";
###request_information = "true";
}
$AllVariables = $RequiredVariables
$Values.Keys | ForEach-Object {
$AllVariables += @{$_ = $values[$_] }
}
$BodyObj = [PSCustomObject]@{
sysparm_quantity = "1";
variables = $AllVariables
}
$BodyJson = $BodyObj | ConvertTo-Json
$InvokeRestMethodParams = @{
Method = 'Post';
Uri = ($Script:ServiceNowSession.Uri + "/api/sn_sc/servicecatalog/items/$CategoryItemSysId/order_now");
Headers = $Script:ServiceNowSession.Headers;
ContentType = $Script:ServiceNowSession.ContentType;
Body = $BodyJson;
}
$InvokeResult = (Invoke-RestMethod @InvokeRestMethodParams).result #create the cart
#$InvokeResult = (Invoke-RestMethod @InvokeRestMethodParams).result
# Submit the cart to create the request
if ($InvokeResult.cart_id) {
$SubmitOrderParams = @{
Method = 'Post'
Uri = ($Script:ServiceNowSession.Uri + "/api/sn_sc/servicecatalog/cart/submit_order")
Headers = $Script:ServiceNowSession.Headers
ContentType = $Script:ServiceNowSession.ContentType
Body = (@{ cart_id = $InvokeResult.cart_id } | ConvertTo-Json)
}
$SubmitResult = (Invoke-RestMethod @SubmitOrderParams).result
} else {
$SubmitResult = $InvokeResult
}
}
end {
Write-Output $SubmitResult
}
}
@@ -0,0 +1,72 @@
<#
.SYNOPSIS
A short one-line action-based description, e.g. 'Tests if a function is valid'
.DESCRIPTION
A longer description of the function, its purpose, common use cases, etc.
.NOTES
Information or caveats about the function e.g. 'This function is not supported in Linux'
.LINK
Specify a URI to a help page, this will show when Get-Help -Online is used.
.EXAMPLE
Test-MyTestFunction -Verbose
Explanation of the function or its result. You can include multiple examples with additional .EXAMPLE lines
#>
function New-ITDServiceNowSession {
[CmdletBinding()]
param (
[Parameter(Mandatory=$true)]
[ValidateSet('Production', 'Test', 'Development')]
[string]
$Environment,
[Parameter(Mandatory=$true)]
[PSCredential]
$Credential
)
begin {
}
process {
switch ($Environment) {
'Production' {
$Url = 'https://northdakota.service-now.com'
}
'Test' {
$Url = 'https://northdakotatest.service-now.com'
}
'Development' {
$Url = 'https://northdakotadev.service-now.com'
}
}
$HeaderAuth = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $Credential.UserName, $Credential.GetNetworkCredential().Password)))
$SNOWSessionHeader = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$SNOWSessionHeader.Add('Authorization', ('Basic {0}' -f $HeaderAuth))
$SNOWSessionHeader.Add('Accept', 'application/json')
$ContentType = "application/json"
$NewSession = @{
Uri = $Url;
Headers = $SNOWSessionHeader;
ContentType = $ContentType;
}
$Script:ServiceNowSession = $newSession
}
end {
}
}
<#
$HeaderAuth = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $SNowVMCred.UserName, $SNowVMCred.GetNetworkCredential().Password)))
$SNOWSessionHeader = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$SNOWSessionHeader.Add('Authorization', ('Basic {0}' -f $HeaderAuth))
$SNOWSessionHeader.Add('Accept', 'application/json')
$ContentType = "application/json"
#>
@@ -0,0 +1,118 @@
<#
.SYNOPSIS
A short one-line action-based description, e.g. 'Tests if a function is valid'
.DESCRIPTION
A longer description of the function, its purpose, common use cases, etc.
.NOTES
Information or caveats about the function e.g. 'This function is not supported in Linux'
.LINK
Specify a URI to a help page, this will show when Get-Help -Online is used.
.EXAMPLE
Test-MyTestFunction -Verbose
Explanation of the function or its result. You can include multiple examples with additional .EXAMPLE lines
#>
function Update-ITDServiceNowRecord {
[CmdletBinding()]
param (
[Parameter(ParameterSetName = 'ItemType')]
[ValidateSet('Incident', 'Change Request', 'User', 'Catalog Task', 'Request Item')]
[string]
$ItemType,
[Parameter(ParameterSetName = 'Table')]
[string]
$Table,
[string]
$SysId,
[string]
$Number,
[hashtable]
$Values
)
begin {
}
process {
switch ($PSCmdlet.ParameterSetName) {
'ItemType' {
$Table = Get-ITDServiceNowTable -ItemType $ItemType
}
'Table' {
# examples: 'cmdb_ci_win_server', 'cmdb_ci_ip_network', 'cmdb_ci_service_auto', 'sc_item_option_mtom'
# don't do anything
}
}
$Uri = ($Script:ServiceNowSession.Uri + "/api/now/table/" + $Table + "?")
#$Uri = ('https://northdakotatest.service-now.com' + "/api/now/table/" + $Table + "?")
switch ($PSBoundParameters.Keys) {
SysId {
Write-Verbose -Message ("sysid passed " + $PSBoundParameters.Item('sysid'))
$Uri += "sys_id=$SysId"
}
Number {
Write-Verbose -Message ("number passed " + $PSBoundParameters.Item('number'))
$Uri += "sysparm_query=number=$Number"
}
}
Write-Verbose $uri
$InvokeRestMethodParams = @{
Method = 'Get';
Uri = $Uri
#Uri = ($Script:ServiceNowSession.Uri + "/api/now/table/" + $Table + "?sysparm_query=number=" + $Number + "&sysparm_limit=1");
Headers = $Script:ServiceNowSession.Headers;
ContentType = $Script:ServiceNowSession.ContentType;
}
try {
$RecordSearch = (Invoke-RestMethod @InvokeRestMethodParams).Result
$Uri = $null
}
catch [System.UriFormatException] {
Write-Error "Invalid URI session. Did you run New-ITDServiceNowSession before execution?"
}
switch (@($RecordSearch).count) { # @($Result).count
{ $_ -lt 1 } {
Write-Error -Message "Record not found"
}
{ $_ -gt 1 } {
Write-Error -Message "More than one record found"
}
{ $_ -eq 1 } {
Write-Verbose -Message 'Exactly one record found'
$SysId = $RecordSearch.sys_id
$Uri = ($Script:ServiceNowSession.Uri + "/api/now/table/" + $Table + "/" + $SysId)
Write-Verbose $Uri
$InvokeRestMethodParams = @{
Method = 'Patch';
Uri = $Uri
Body = $Values | ConvertTo-Json;
Headers = $Script:ServiceNowSession.Headers;
ContentType = $Script:ServiceNowSession.ContentType;
}
try {
$UpdateResult = (Invoke-RestMethod @InvokeRestMethodParams).Result
}
catch [System.UriFormatException] {
Write-Error "Invalid URI session. Did you run New-ITDServiceNowSession before execution?"
}
}
}
}
end {
Write-Output $UpdateResult
}
}