Skip to content

Commit 33bd644

Browse files
committed
add advanced filtering
1 parent 49f465c commit 33bd644

File tree

8 files changed

+422
-38
lines changed

8 files changed

+422
-38
lines changed

ServiceNow/Private/Invoke-ServiceNowRestMethod.ps1

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ function Invoke-ServiceNowRestMethod {
3939
[parameter()]
4040
[hashtable] $Values,
4141

42+
[parameter()]
43+
[System.Collections.ArrayList] $Filter,
44+
45+
[parameter()]
46+
[ValidateNotNullOrEmpty()]
47+
[System.Collections.ArrayList] $Order = @('opened_at', 'desc'),
48+
4249
# sysparm_query param in the format of a ServiceNow encoded query string (see http://wiki.servicenow.com/index.php?title=Encoded_Query_Strings)
4350
[Parameter()]
4451
[string] $Query,
@@ -135,6 +142,8 @@ function Invoke-ServiceNowRestMethod {
135142
# Populate the query
136143
if ($Query) {
137144
$Body.sysparm_query = $Query
145+
} else {
146+
$body.sysparm_query = (New-ServiceNowQuery -Filter $Filter -Order $Order)
138147
}
139148

140149
if ($Properties) {
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
function Get-ServiceNowRecord {
2+
<#
3+
.SYNOPSIS
4+
Retrieves records for the specified table
5+
.DESCRIPTION
6+
The Get-ServiceNowTable function retrieves records for the specified table
7+
.INPUTS
8+
None
9+
.OUTPUTS
10+
System.Management.Automation.PSCustomObject
11+
.LINK
12+
Service-Now Kingston REST Table API: https://docs.servicenow.com/bundle/kingston-application-development/page/integrate/inbound-rest/concept/c_TableAPI.html
13+
Service-Now Table API FAQ: https://hi.service-now.com/kb_view.do?sysparm_article=KB0534905
14+
#>
15+
16+
[OutputType([System.Management.Automation.PSCustomObject])]
17+
[CmdletBinding(DefaultParameterSetName = 'Session', SupportsPaging)]
18+
19+
Param (
20+
# Name of the table we're querying (e.g. incidents)
21+
[parameter(Mandatory)]
22+
[ValidateNotNullOrEmpty()]
23+
[string] $Table,
24+
25+
[parameter(ParameterSetName = 'AutomationFilter')]
26+
[parameter(ParameterSetName = 'SessionFilter')]
27+
[System.Collections.ArrayList] $Filter,
28+
29+
[parameter(ParameterSetName = 'AutomationFilter')]
30+
[parameter(ParameterSetName = 'SessionFilter')]
31+
[ValidateNotNullOrEmpty()]
32+
[System.Collections.ArrayList] $Order,
33+
34+
# sysparm_query param in the format of a ServiceNow encoded query string (see http://wiki.servicenow.com/index.php?title=Encoded_Query_Strings)
35+
[Parameter(Mandatory, ParameterSetName = 'AutomationQuery')]
36+
[Parameter(Mandatory, ParameterSetName = 'SessionQuery')]
37+
[string] $Query,
38+
39+
# Fields to return
40+
[Parameter()]
41+
[Alias('Fields')]
42+
[string[]] $Properties,
43+
44+
# Whether or not to show human readable display values instead of machine values
45+
[Parameter()]
46+
[ValidateSet('true', 'false', 'all')]
47+
[string] $DisplayValues = 'true',
48+
49+
[Parameter(Mandatory, ParameterSetName = 'AutomationQuery')]
50+
[parameter(Mandatory, ParameterSetName = 'AutomationFilter')]
51+
[ValidateNotNullOrEmpty()]
52+
[hashtable] $Connection,
53+
54+
[Parameter(ParameterSetName = 'SessionQuery')]
55+
[Parameter(ParameterSetName = 'SessionFilter')]
56+
[ValidateNotNullOrEmpty()]
57+
[hashtable] $ServiceNowSession = $script:ServiceNowSession
58+
)
59+
60+
# $params = $PSBoundParameters
61+
62+
# Add all provided paging parameters
63+
# ($PSCmdlet.PagingParameters | Get-Member -MemberType Property).Name | ForEach-Object {
64+
# $params.Add($_, $PSCmdlet.PagingParameters.$_)
65+
# }
66+
67+
$result = Invoke-ServiceNowRestMethod @PSBoundParameters
68+
69+
If ( $result -and -not $Properties) {
70+
$type = $script:ServiceNowTable | Where-Object {$_.DbTableName -eq $Table} | Select-Object -ExpandProperty Type
71+
if ($type) {
72+
$result | ForEach-Object { $_.PSObject.TypeNames.Insert(0, $type) }
73+
}
74+
}
75+
76+
$result
77+
}

ServiceNow/Public/Get-ServiceNowTableEntry.ps1

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,52 +23,52 @@ function Get-ServiceNowTableEntry {
2323
param(
2424
# Table containing the entry we're deleting
2525
[parameter(Mandatory)]
26-
[string]$Table,
26+
[string] $Table,
2727

2828
# Machine name of the field to order by
2929
[parameter()]
30-
[string]$OrderBy = 'opened_at',
30+
[string] $OrderBy = 'opened_at',
3131

3232
# Direction of ordering (Desc/Asc)
3333
[parameter()]
3434
[ValidateSet('Desc', 'Asc')]
35-
[string]$OrderDirection = 'Desc',
35+
[string] $OrderDirection = 'Desc',
3636

3737
# Maximum number of records to return
3838
[parameter()]
39-
[int]$Limit,
39+
[int] $Limit,
4040

4141
# Fields to return
4242
[Parameter()]
4343
[Alias('Fields')]
44-
[string[]]$Properties,
44+
[string[]] $Properties,
4545

4646
# Hashtable containing machine field names and values returned must match exactly (will be combined with AND)
4747
[parameter()]
48-
[hashtable]$MatchExact = @{},
48+
[hashtable] $MatchExact = @{},
4949

5050
# Hashtable containing machine field names and values returned rows must contain (will be combined with AND)
5151
[parameter()]
52-
[hashtable]$MatchContains = @{},
52+
[hashtable] $MatchContains = @{},
5353

5454
# Whether or not to show human readable display values instead of machine values
5555
[parameter()]
5656
[ValidateSet('true', 'false', 'all')]
57-
[string]$DisplayValues = 'true',
57+
[string] $DisplayValues = 'true',
5858

5959
[Parameter(ParameterSetName = 'SpecifyConnectionFields', Mandatory)]
6060
[ValidateNotNullOrEmpty()]
6161
[Alias('ServiceNowCredential')]
62-
[PSCredential]$Credential,
62+
[PSCredential] $Credential,
6363

6464
[Parameter(ParameterSetName = 'SpecifyConnectionFields', Mandatory)]
6565
[ValidateScript( { $_ | Test-ServiceNowURL })]
6666
[Alias('Url')]
67-
[string]$ServiceNowURL,
67+
[string] $ServiceNowURL,
6868

6969
[Parameter(ParameterSetName = 'UseConnectionObject', Mandatory)]
7070
[ValidateNotNullOrEmpty()]
71-
[hashtable]$Connection,
71+
[hashtable] $Connection,
7272

7373
[Parameter(ParameterSetName = 'Session')]
7474
[ValidateNotNullOrEmpty()]

ServiceNow/Public/New-ServiceNowQuery.ps1

Lines changed: 164 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,41 +18,189 @@ function New-ServiceNowQuery {
1818
String
1919
#>
2020

21-
# This function doesn't change state. Doesn't justify ShouldProcess functionality
22-
[System.Diagnostics.CodeAnalysis.SuppressMessage('PSUseShouldProcessForStateChangingFunctions','')]
21+
[System.Diagnostics.CodeAnalysis.SuppressMessage('PSUseShouldProcessForStateChangingFunctions', 'No state is actually changing')]
2322

2423
[CmdletBinding()]
2524
[OutputType([System.String])]
2625

2726
param(
2827
# Machine name of the field to order by
29-
[parameter()]
30-
[string]$OrderBy='opened_at',
28+
[parameter(ParameterSetName = 'Basic')]
29+
[string] $OrderBy = 'opened_at',
3130

3231
# Direction of ordering (Desc/Asc)
33-
[parameter()]
32+
[parameter(ParameterSetName = 'Basic')]
3433
[ValidateSet("Desc", "Asc")]
35-
[string]$OrderDirection='Desc',
34+
[string] $OrderDirection = 'Desc',
3635

3736
# Hashtable containing machine field names and values returned must match exactly (will be combined with AND)
38-
[parameter()]
39-
[hashtable]$MatchExact,
37+
[parameter(ParameterSetName = 'Basic')]
38+
[hashtable] $MatchExact,
4039

4140
# Hashtable containing machine field names and values returned rows must contain (will be combined with AND)
42-
[parameter()]
43-
[hashtable]$MatchContains
41+
[parameter(ParameterSetName = 'Basic')]
42+
[hashtable] $MatchContains,
43+
44+
[parameter(ParameterSetName = 'Advanced')]
45+
[System.Collections.ArrayList] $Filter,
46+
47+
[parameter(ParameterSetName = 'Advanced')]
48+
[ValidateNotNullOrEmpty()]
49+
[System.Collections.ArrayList] $Order = @('opened_at', 'desc')
50+
4451
)
4552

46-
Try {
53+
Write-Verbose ('{0} - {1}' -f $MyInvocation.MyCommand, $PSCmdlet.ParameterSetName)
54+
55+
if ( $PSCmdlet.ParameterSetName -eq 'Advanced' ) {
56+
if ( $Filter ) {
57+
$filterList = $Filter
58+
# see if we're working with 1 array or multidimensional array
59+
# we're looking for multidimensional so convert if not
60+
if ($Filter[0].GetType().Name -eq 'String') {
61+
$filterList = @(, $Filter)
62+
}
63+
64+
$query = for ($i = 0; $i -lt $filterList.Count; $i++) {
65+
$thisFilter = $filterList[$i]
66+
67+
# allow passing of string instead of array
68+
# useful for joins
69+
if ($thisFilter.GetType().Name -eq 'String') {
70+
$thisFilter = @(, $thisFilter)
71+
}
72+
73+
switch ($thisFilter.Count) {
74+
0 {
75+
# nothing to see here
76+
Continue
77+
}
78+
79+
1 {
80+
# should be a join
81+
82+
switch ($thisFilter[0]) {
83+
'and' {
84+
'^'
85+
}
86+
87+
'or' {
88+
'^OR'
89+
}
90+
91+
'group' {
92+
'^NQ'
93+
}
94+
95+
Default {
96+
throw "Unsupported join operator '$($thisFilter[0])'. 'and', 'or', and 'group' are supported."
97+
}
98+
}
99+
100+
# make sure we don't end on a join
101+
if ( $i -eq $filterList.Count - 1) {
102+
throw '$Filter cannot end with a join'
103+
}
104+
}
105+
106+
2 {
107+
# should be a non-value operator
108+
$thisOperator = $script:ServiceNowOperator | Where-Object { $_.Name -eq $thisFilter[1] }
109+
if ( -not $thisOperator ) {
110+
throw ('Operator ''{0}'' is not valid' -f $thisFilter[1])
111+
}
112+
if ( $thisOperator.RequiresValue ) {
113+
throw ('Value not provided, {0} {1} ?' -f $thisFilter[0], $thisOperator.QueryOperator)
114+
}
115+
'{0}{1}' -f $thisFilter[0], $thisOperator.QueryOperator
116+
}
117+
118+
3 {
119+
# should be key operator value
120+
$thisOperator = $script:ServiceNowOperator | Where-Object { $_.Name -eq $thisFilter[1] }
121+
if ( -not $thisOperator ) {
122+
throw ('Operator ''{0}'' is not valid', $thisFilter[1])
123+
}
124+
'{0}{1}{2}' -f $thisFilter[0], $thisOperator.QueryOperator, $thisFilter[2]
125+
}
126+
127+
Default {
128+
throw ('Too many items for {0}, see the help' -f $thisFilter[0])
129+
}
130+
}
131+
}
132+
}
133+
134+
# force query to an array in case we only got one item and its a string
135+
# otherwise below add to query won't work as expected
136+
$query = @($query)
137+
138+
if ($query) {
139+
$query += '^'
140+
}
141+
142+
$orderList = $Order
143+
# see if we're working with 1 array or multidimensional array
144+
# we're looking for multidimensional so convert if not
145+
if ($Order[0].GetType().Name -eq 'String') {
146+
$orderList = @(, $Order)
147+
}
148+
149+
$query += for ($i = 0; $i -lt $orderList.Count; $i++) {
150+
$thisOrder = $orderList[$i]
151+
if ( $orderList.Count -gt 1 -and $i -gt 0 ) {
152+
'^'
153+
}
154+
155+
switch ($thisOrder.Count) {
156+
0 {
157+
# nothing to see here
158+
Continue
159+
}
160+
161+
1 {
162+
# should be field, default to ascending
163+
'ORDERBY'
164+
$thisOrder[0]
165+
}
166+
167+
2 {
168+
switch ($thisOrder[1]) {
169+
'asc' {
170+
'ORDERBY'
171+
}
172+
173+
'desc' {
174+
'ORDERBYDESC'
175+
}
176+
177+
Default {
178+
throw "Invalid order direction '$_'. Provide either 'asc' or 'desc'."
179+
}
180+
}
181+
$thisOrder[0]
182+
}
183+
184+
Default {
185+
throw ('Too many items for {0}, see the help' -f $thisOrder[0])
186+
}
187+
}
188+
}
189+
190+
$query -join ''
191+
192+
} else {
193+
# Basic parameter set
194+
47195
# Create StringBuilder
48196
$Query = New-Object System.Text.StringBuilder
49197

50198
# Start the query off with a order direction
51-
$Order = Switch ($OrderDirection) {
52-
'Asc' {'ORDERBY'; break}
53-
Default {'ORDERBYDESC'}
199+
$direction = Switch ($OrderDirection) {
200+
'Asc' { 'ORDERBY'; break }
201+
Default { 'ORDERBYDESC' }
54202
}
55-
[void]$Query.Append($Order)
203+
[void]$Query.Append($direction)
56204

57205
# Add OrderBy
58206
[void]$Query.Append($OrderBy)
@@ -76,7 +224,4 @@ function New-ServiceNowQuery {
76224
# Output StringBuilder to string
77225
$Query.ToString()
78226
}
79-
Catch {
80-
Write-Error $PSItem
81-
}
82-
}
227+
}

ServiceNow/Public/New-ServiceNowSession.ps1

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,18 @@ function New-ServiceNowSession {
166166
}
167167
}
168168

169+
$cmdbParams = @{
170+
Table = 'sys_db_object'
171+
Query = 'nameSTARTSWITHcmdb_ci'
172+
Properties = 'name', 'sys_id', 'label'
173+
First = 10000
174+
ServiceNowSession = $newSession
175+
}
176+
$ci = Get-ServiceNowTable @cmdbParams -ErrorAction SilentlyContinue
177+
if ( $ci ) {
178+
$newSession.Add('CmdbClasses', $ci)
179+
}
180+
169181
Write-Verbose ($newSession | ConvertTo-Json)
170182

171183
if ( $PassThru ) {

0 commit comments

Comments
 (0)