/
Invoke-WTValidateSubscription.ps1
208 lines (189 loc) · 8.95 KB
/
Invoke-WTValidateSubscription.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
function Invoke-WTValidateSubscription {
[CmdletBinding()]
param (
[parameter(
Mandatory = $false,
ValueFromPipeLineByPropertyName = $true,
HelpMessage = "The file path to the JSON file(s) that will be imported"
)]
[string[]]$FilePath,
[parameter(
Mandatory = $false,
ValueFromPipeLineByPropertyName = $true,
HelpMessage = "The directory path(s) of which all JSON file(s) will be imported"
)]
[string]$Path,
[parameter(
Mandatory = $false,
ValueFromPipeLineByPropertyName = $true,
ValueFromPipeLine = $true,
HelpMessage = "The Azure AD Subscriptions to be validated if not imported from a JSON file"
)]
[Alias('Subscription', 'SubscriptionDefinition')]
[PSCustomObject]$DefinedSubscriptions,
[parameter(
Mandatory = $false,
ValueFromPipeLineByPropertyName = $true,
HelpMessage = "Specify whether files should be imported only, and not validated"
)]
[switch]$ImportOnly
)
Begin {
try {
# Variables
$RequiredProperties = @("skuPartNumber","skuId","servicePlans","capabilityStatus","appliesTo")
}
catch {
Write-Error -Message $_.Exception
throw $_.exception
}
}
Process {
try {
# For each directory, get the file path of all JSON files within the directory, if the directory exists
if ($Path) {
$PathExists = Test-Path -Path $Path
if ($PathExists) {
$FilePath = (Get-ChildItem -Path $Path -Filter "*.json").FullName
}
else {
$ErrorMessage = "The provided path does not exist $Path, please check the path is correct"
throw $ErrorMessage
}
}
# Import Subscriptions from JSON file, if the files exist
if ($FilePath) {
$SubscriptionImport = foreach ($File in $FilePath) {
$FilePathExists = Test-Path -Path $File
if ($FilePathExists) {
Get-Content -Raw -Path $File
}
else {
$ErrorMessage = "The provided filepath $File does not exist, please check the path is correct"
throw $ErrorMessage
}
}
# If import was successful, convert from JSON
if ($SubscriptionImport) {
$DefinedSubscriptions = $SubscriptionImport | ConvertFrom-Json
}
else {
$ErrorMessage = "No JSON files could be imported, please check the filepath is correct"
throw $ErrorMessage
}
}
# If there are subscriptions imported, run validation checks
if ($DefinedSubscriptions) {
# Output current action
Write-Host "Importing Defined Subscriptions"
Write-Host "Subscriptions: $($DefinedSubscriptions.count)"
foreach ($Subscription in $DefinedSubscriptions) {
if ($Subscription.skuPartNumber) {
Write-Host "Import: Subscription Name: $($Subscription.skuPartNumber)"
}
elseif ($Subscription.id) {
Write-Host "Import: Subscription Id: $($Subscription.id)"
}
else {
Write-Host "Import: Subscription Invalid"
}
}
# If import only is set, return subscriptions without validating
if ($ImportOnly) {
$DefinedSubscriptions
}
else {
# Output current action
Write-Host "Validating Defined Subscriptions"
# For each policy, run validation checks
$InvalidSubscriptions = foreach ($Subscription in $DefinedSubscriptions) {
$SubscriptionValidate = $null
# Check for missing properties
$SubscriptionProperties = $null
$SubscriptionProperties = ($Subscription | Get-Member -MemberType NoteProperty).name
$PropertyCheck = $null
# Check whether each required property, exists in the list of properties for the object
$PropertyCheck = foreach ($Property in $RequiredProperties) {
if ($Property -notin $SubscriptionProperties) {
$Property
}
}
# Check whether each required property has a value, if not, return property
$PropertyValueCheck = $null
$PropertyValueCheck = foreach ($Property in $RequiredProperties) {
if ($null -eq $Subscription.$Property) {
$Property
}
}
# Build and return object
if ($PropertyCheck -or $PropertyValueCheck) {
$SubscriptionValidate = [ordered]@{}
if ($Subscription.skuPartNumber) {
$SubscriptionValidate.Add("skuPartNumber", $Subscription.skuPartNumber)
}
elseif ($Subscription.id) {
$SubscriptionValidate.Add("Id", $Subscription.id)
}
}
if ($PropertyCheck) {
$SubscriptionValidate.Add("MissingProperties", $PropertyCheck)
}
if ($PropertyValueCheck) {
$SubscriptionValidate.Add("MissingPropertyValues", $PropertyValueCheck)
}
if ($SubscriptionValidate) {
[PSCustomObject]$SubscriptionValidate
}
}
# Return validation result for each policy
if ($InvalidSubscriptions) {
Write-Host "Invalid subscriptions: $($InvalidSubscriptions.count) out of $($DefinedSubscriptions.count) imported"
foreach ($Subscription in $InvalidSubscriptions) {
if ($Subscription.skuPartNumber) {
Write-Host "INVALID: Subscription Name: $($Subscription.skuPartNumber)" -ForegroundColor Yellow
}
elseif ($Subscription.id) {
Write-Host "INVALID: Subscription Id: $($Subscription.id)" -ForegroundColor Yellow
}
else {
Write-Host "INVALID: No skuPartNumber or Id for policy" -ForegroundColor Yellow
}
if ($Subscription.MissingProperties) {
Write-Warning "Required properties not present ($($Subscription.MissingProperties.count)): $($Subscription.MissingProperties)"
}
if ($Subscription.MissingPropertyValues) {
Write-Warning "Required property values not present ($($Subscription.MissingPropertyValues.count)): $($Subscription.MissingPropertyValues)"
}
}
# Abort import
$ErrorMessage = "Validation of subscriptions was not successful, review configuration files and any warnings generated"
Write-Error $ErrorMessage
throw $ErrorMessage
}
else {
# Return validated subscriptions
Write-Host "All subscriptions have passed validation for required properties and values"
$ValidSubscriptions = $DefinedSubscriptions
$ValidSubscriptions
}
}
}
else {
$ErrorMessage = "No Subscriptions to be imported, import may have failed or none may exist"
throw $ErrorMessage
}
}
catch {
Write-Error -Message $_.Exception
throw $_.exception
}
}
End {
try {
}
catch {
Write-Error -Message $_.Exception
throw $_.exception
}
}
}