diff --git a/RBAC/RBAC_ScopeTags_PolicyAssign.ps1 b/RBAC/RBAC_ScopeTags_PolicyAssign.ps1 index c9cb25a..71febc6 100644 --- a/RBAC/RBAC_ScopeTags_PolicyAssign.ps1 +++ b/RBAC/RBAC_ScopeTags_PolicyAssign.ps1 @@ -1,6 +1,6 @@ - + <# -  + .COPYRIGHT Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information. @@ -8,7 +8,8 @@ See LICENSE in the project root for license information. #> #################################################### -  + + function Get-AuthToken { <# @@ -89,13 +90,15 @@ Write-Host "Checking for AzureAD module..." [System.Reflection.Assembly]::LoadFrom($adalforms) | Out-Null $clientId = "d1ddf0e4-d672-4dae-b554-9d5bdfd93547" -  + $redirectUri = "urn:ietf:wg:oauth:2.0:oob" -  + +#This needs to be changed for DOD to "https://graph.microsoft.com" $resourceAppIdURI = "https://graph.microsoft.com" -  + +#This needs to be changed for DOD to "https://login.microsoftonline.com/$Tenant" $authority = "https://login.microsoftonline.com/$Tenant" -  + try { $authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority @@ -105,7 +108,7 @@ $authority = "https://login.microsoftonline.com/$Tenant" $platformParameters = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.PlatformParameters" -ArgumentList "Auto" - $userId = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.UserIdentifier" -ArgumentList ($User, "OptionalDisplayableId") + $userId = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.comerIdentifier" -ArgumentList ($User, "OptionalDisplayableId") $authResult = $authContext.AcquireTokenAsync($resourceAppIdURI,$clientId,$redirectUri,$platformParameters,$userId).Result @@ -146,7 +149,7 @@ $authority = "https://login.microsoftonline.com/$Tenant" } } -  + #################################################### Function Get-DeviceCompliancePolicy(){ @@ -305,10 +308,180 @@ $DCP_resource = "deviceManagement/deviceConfigurations" else { $uri = "https://graph.microsoft.com/$graphApiVersion/$($DCP_resource)" - (Invoke-RestMethod -Uri $uri -Headers $authToken -Method Get).Value + $results=Invoke-RestMethod -Uri $uri -Headers $authToken -Method Get + $value=$results.value + $pages=$results.'@odata.nextlink' + while($null -ne $pages){ + $additional=(Invoke-RestMethod -Uri $pages -Headers $authToken -Method Get) + if($pages){ + $value+=$additional.Value + $pages=$additional."@odata.nextlink" + } + } + return $value + + } + + } + + catch { + + $ex = $_.Exception + $errorResponse = $ex.Response.GetResponseStream() + $reader = New-Object System.IO.StreamReader($errorResponse) + $reader.BaseStream.Position = 0 + $reader.DiscardBufferedData() + $responseBody = $reader.ReadToEnd(); + Write-Host "Response content:`n$responseBody" -f Red + Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" + write-host + break + + } + +} + + +#################################################### + +Function Get-DeviceConfigurationAdminTemplates(){ + +<# +.SYNOPSIS +This function is used to get device configuration policies from the Graph API REST interface +.DESCRIPTION +The function connects to the Graph API Interface and gets any device configuration policies +.EXAMPLE +Get-DeviceConfigurationPolicy +Returns any device configuration policies configured in Intune +.NOTES +NAME: Get-DeviceConfigurationPolicy +#> + +[cmdletbinding()] + +param +( + $name, + $id +) + +$graphApiVersion = "Beta" +$DCP_resource = "deviceManagement/groupPolicyConfigurations" + + try { + + if($Name){ + + $uri = "https://graph.microsoft.com/$graphApiVersion/$($DCP_resource)" + (Invoke-RestMethod -Uri $uri -Headers $authToken -Method Get).Value | Where-Object { ($_.'displayName').contains("$Name") } + + } + + elseif($id){ + + $uri = "https://graph.microsoft.com/$graphApiVersion/$($DCP_resource)/$id" + Invoke-RestMethod -Uri $uri -Headers $authToken -Method Get + + } + + else { + + $uri = "https://graph.microsoft.com/$graphApiVersion/$($DCP_resource)" + + $results=Invoke-RestMethod -Uri $uri -Headers $authToken -Method Get + $value=$results.value + $pages=$results.'@odata.nextlink' + while($null -ne $pages){ + $additional=(Invoke-RestMethod -Uri $pages -Headers $authToken -Method Get) + if($pages){ + $value+=$additional.Value + $pages=$additional."@odata.nextlink" + } + } + return $value + } + + } + + catch { + + $ex = $_.Exception + $errorResponse = $ex.Response.GetResponseStream() + $reader = New-Object System.IO.StreamReader($errorResponse) + $reader.BaseStream.Position = 0 + $reader.DiscardBufferedData() + $responseBody = $reader.ReadToEnd(); + Write-Host "Response content:`n$responseBody" -f Red + Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" + write-host + break + + } + +} + + +#################################################### + +Function Get-DeviceConfigurationSettingsCatalog(){ + +<# +.SYNOPSIS +This function is used to get device configuration policies from the Graph API REST interface +.DESCRIPTION +The function connects to the Graph API Interface and gets any device configuration policies +.EXAMPLE +Get-DeviceConfigurationPolicy +Returns any device configuration policies configured in Intune +.NOTES +NAME: Get-DeviceConfigurationPolicy +#> + +[cmdletbinding()] + +param +( + $name, + $id +) + +$graphApiVersion = "Beta" +$DCP_resource = "deviceManagement/configurationPolicies" + + try { + + if($Name){ + + $uri = "https://graph.microsoft.com/$graphApiVersion/$($DCP_resource)" + (Invoke-RestMethod -Uri $uri -Headers $authToken -Method Get).Value | Where-Object { ($_.'Name').contains("$Name") } + + } + + elseif($id){ + + $uri = "https://graph.microsoft.com/$graphApiVersion/$($DCP_resource)/$id" + Invoke-RestMethod -Uri $uri -Headers $authToken -Method Get } + else { + + $uri = "https://graph.microsoft.com/$graphApiVersion/$($DCP_resource)" + + $results=Invoke-RestMethod -Uri $uri -Headers $authToken -Method Get + $value=$results.value + $pages=$results.'@odata.nextlink' + while($null -ne $pages){ + $additional=(Invoke-RestMethod -Uri $pages -Headers $authToken -Method Get) + if($pages){ + $value+=$additional.Value + $pages=$additional."@odata.nextlink" + } + } + return $value + } + } catch { @@ -328,6 +501,7 @@ $DCP_resource = "deviceManagement/deviceConfigurations" } + #################################################### Function Update-DeviceCompliancePolicy(){ @@ -375,7 +549,7 @@ $JSON = @" else { - $object = New-Object –TypeName PSObject + $object = New-Object -TypeName PSObject $object | Add-Member -MemberType NoteProperty -Name '@odata.type' -Value "$Type" $object | Add-Member -MemberType NoteProperty -Name 'roleScopeTagIds' -Value @($ScopeTags) $JSON = $object | ConvertTo-Json @@ -454,7 +628,7 @@ $JSON = @" else { - $object = New-Object –TypeName PSObject + $object = New-Object -TypeName PSObject $object | Add-Member -MemberType NoteProperty -Name '@odata.type' -Value "$Type" $object | Add-Member -MemberType NoteProperty -Name 'roleScopeTagIds' -Value @($ScopeTags) $JSON = $object | ConvertTo-Json @@ -486,6 +660,168 @@ $JSON = @" } + +#################################################### + +Function Update-DeviceConfigurationAdminTemplate(){ + +<# +.SYNOPSIS +This function is used to update a device configuration policy using the Graph API REST interface +.DESCRIPTION +The function connects to the Graph API Interface and updates a device configuration policy +.EXAMPLE +Update-DeviceConfigurationPolicy -id $Policy.id -Type $Type -ScopeTags "1" +Updates an device configuration policy in Intune +.NOTES +NAME: Update-DeviceConfigurationPolicy +#> + +[cmdletbinding()] + +param +( + [Parameter(Mandatory=$true)] + $id, + # [Parameter(Mandatory=$true)] + # $Type, + [Parameter(Mandatory=$true)] + $ScopeTags +) + +$graphApiVersion = "beta" +$Resource = "deviceManagement/groupPolicyConfigurations/$id" + + try { + + if($ScopeTags -eq "" -or $ScopeTags -eq $null){ + +$JSON = @" + +{ + + "roleScopeTagIds": [] +} + +"@ +#took this out of the jason config above just above "roleScopeTagIDs" "@odata.type": "$Type", + } + + else { + + $object = New-Object -TypeName PSObject + #$object | Add-Member -MemberType NoteProperty -Name '@odata.type' -Value "$Type" + $object | Add-Member -MemberType NoteProperty -Name 'roleScopeTagIds' -Value @($ScopeTags) + $JSON = $object | ConvertTo-Json + + } + + $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)" + Invoke-RestMethod -Uri $uri -Headers $authToken -Method Patch -Body $JSON -ContentType "application/json" + + Start-Sleep -Milliseconds 100 + + } + + catch { + + Write-Host + $ex = $_.Exception + $errorResponse = $ex.Response.GetResponseStream() + $reader = New-Object System.IO.StreamReader($errorResponse) + $reader.BaseStream.Position = 0 + $reader.DiscardBufferedData() + $responseBody = $reader.ReadToEnd(); + Write-Host "Response content:`n$responseBody" -f Red + Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" + write-host + break + + } + +} + +#################################################### + +Function Update-DeviceConfigurationSettingsCatalog(){ + +<# +.SYNOPSIS +This function is used to update a device configuration policy using the Graph API REST interface +.DESCRIPTION +The function connects to the Graph API Interface and updates a device configuration policy +.EXAMPLE +Update-DeviceConfigurationPolicy -id $Policy.id -Type $Type -ScopeTags "1" +Updates an device configuration policy in Intune +.NOTES +NAME: Update-DeviceConfigurationPolicy +#> + +[cmdletbinding()] + +param +( + [Parameter(Mandatory=$true)] + $id, + # [Parameter(Mandatory=$true)] + # $Type, + [Parameter(Mandatory=$true)] + $ScopeTags +) + +$graphApiVersion = "beta" +$Resource = "deviceManagement/configurationPolicies/$id" + + try { + + if($ScopeTags -eq "" -or $ScopeTags -eq $null){ + +$JSON = @" + +{ + + "roleScopeTagIds": [] +} + +"@ +#took this out of the jason config above just above "roleScopeTagIDs" "@odata.type": "$Type", + } + + else { + + $object = New-Object -TypeName PSObject + #$object | Add-Member -MemberType NoteProperty -Name '@odata.type' -Value "$Type" + $object | Add-Member -MemberType NoteProperty -Name 'roleScopeTagIds' -Value @($ScopeTags) + $JSON = $object | ConvertTo-Json + + } + + $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)" + Invoke-RestMethod -Uri $uri -Headers $authToken -Method Patch -Body $JSON -ContentType "application/json" + + Start-Sleep -Milliseconds 100 + + } + + catch { + + Write-Host + $ex = $_.Exception + $errorResponse = $ex.Response.GetResponseStream() + $reader = New-Object System.IO.StreamReader($errorResponse) + $reader.BaseStream.Position = 0 + $reader.DiscardBufferedData() + $responseBody = $reader.ReadToEnd(); + Write-Host "Response content:`n$responseBody" -f Red + Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" + write-host + break + + } + +} + + #################################################### Function Get-RBACScopeTag(){ @@ -526,7 +862,21 @@ $Resource = "deviceManagement/roleScopeTags" else { $uri = "https://graph.microsoft.com/$graphApiVersion/$Resource" - $Result = (Invoke-RestMethod -Uri $uri -Method Get -Headers $authToken).Value + + + # $Result = (Invoke-RestMethod -Uri $uri -Method Get -Headers $authToken).Value + + $results=Invoke-RestMethod -Uri $uri -Headers $authToken -Method Get + $Result=$results.value + $pages=$results.'@odata.nextlink' + while($null -ne $pages){ + $additional=(Invoke-RestMethod -Uri $pages -Headers $authToken -Method Get) + if($pages){ + $Result+=$additional.Value + $pages=$additional."@odata.nextlink" + } + } + return $Result } @@ -604,9 +954,9 @@ $global:authToken = Get-AuthToken -User $User #################################################### -Write-Host "Are you sure you want to add Scope Tags to all Configuration and Compliance Policies? Y or N?" -$Confirm = read-host - +#Write-Host "Are you sure you want to add Scope Tags to all Configuration and Compliance Policies? Y or N?" +#$Confirm = read-host +$Confirm = "Y" if($Confirm -eq "y" -or $Confirm -eq "Y"){ Write-Host "Checking if any Scope Tags have been created..." @@ -614,6 +964,81 @@ if($Confirm -eq "y" -or $Confirm -eq "Y"){ $ScopeTags = Get-RBACScopeTag + #Modify here so we only work with 1 scope tag at a time instead of all the existing ScopeTags. We do need the '*' as we are using the -like operator. May want to put user input reads to type the Tag name + Write-host "Please type the Scope Tag you would like to apply (Full and correct scope Tag name)" + #region ScopeTags Menu + +Write-Host + +$ScopeTags1 = (Get-RBACScopeTag).displayName | Sort-Object + +if($ScopeTags1){ + +Write-Host "Please specify Scope Tag you want to add to all users / devices in AAD Group:" -ForegroundColor Yellow + +$menu = @{} + +for ($i=1;$i -le $ScopeTags1.count; $i++) +{ Write-Host "$i. $($ScopeTags1[$i-1])" +$menu.Add($i,($ScopeTags1[$i-1]))} + +Write-Host +$ans = Read-Host 'Enter Scope Tag id (Numerical value)' + +if($ans -eq "" -or $ans -eq $null){ + + Write-Host "Scope Tag can't be null, please specify a valid Scope Tag..." -ForegroundColor Red + Write-Host + break + +} + +elseif(($ans -match "^[\d\.]+$") -eq $true){ + +$selection = $menu.Item([int]$ans) + + if($selection){ + + $ScopeTagId = (Get-RBACScopeTag | Where-Object { $_.displayName -eq "$selection" }).id + $inTag= $selection + } + + else { + + Write-Host "Scope Tag selection invalid, please specify a valid Scope Tag..." -ForegroundColor Red + Write-Host + break + + } + +} + +else { + + Write-Host "Scope Tag not an integer, please specify a valid scope tag..." -ForegroundColor Red + Write-Host + break + +} + +Write-Host + +} + +else { + + Write-Host "No Scope Tags created, script can't continue..." -ForegroundColor Red + Write-Host + break + +} + +#endregion + + + + $ScopeTags = $ScopeTags | ?{$_.displayname -eq $inTag} + if($ScopeTags){ Write-Host "Scope Tags found..." -ForegroundColor Green @@ -630,11 +1055,23 @@ if($Confirm -eq "y" -or $Confirm -eq "Y"){ #region Device Compliance Policies - Write-Host "Testing if '$ScopeTag_DN' exists in Device Compliance Policy Display Name..." - - $CPs = Get-DeviceCompliancePolicy | Where-Object { ($_.displayName).contains("$ScopeTag_DN") } | Sort-Object displayName + Write-Host "Type the pattern name of the Compliance Policies you'd like to apply the ScopeTag provided (Compliance Policy name is case sensitive)" + $inCP=read-host +# This is where we update the Complicance Policy names so it only targets anything containing the specified text, no need for '*' as we are using contains operator + $CPs = Get-DeviceCompliancePolicy | Where-Object { ($_.displayName).contains($inCP) } | Sort-Object displayName + if($CPs){ + write-host "These are the identified Compliance Policies that would be tagged with $($ScopeTag.DisplayName)" + foreach($cpls in $CPs){ + write-host $CPls.displayName -foregroundcolor Cyan } + write-host "Are you sure you want to proceed (Y/N)?" + $answerCP=read-host + } + else + { + Write-Host "There were no Compliance Policies that matched your name pattern" -foregroundcolor Red + } - if($CPs){ + if(($CPs) -and (($answerCP -eq "Y") -or ($answerCP -eq "y"))){ foreach($Policy in $CPs){ @@ -692,11 +1129,29 @@ if($Confirm -eq "y" -or $Confirm -eq "Y"){ #region Device Configuration Policies - Write-Host "Testing if '$ScopeTag_DN' exists in Device Configuration Policy Display Name..." + Write-Host "Type the pattern name of the Configuration Profiles you'd like to apply the scope tag provided (Configuration profile name is case sensitive)" + $inDCP=read-host - $DCPs = Get-DeviceConfigurationPolicy | Where-Object { ($_.displayName).contains("$ScopeTag_DN") } | Sort-Object displayName +#Update this displayName.contains with the name/names or wildcard of the Configuration profiles that we want to update no need for a '*' in the contains section + $DCPs = Get-DeviceConfigurationPolicy | Where-Object { ($_.displayName).contains($inDCP) } | Sort-Object displayName + $AdmTemp=Get-DeviceConfigurationAdminTemplates | Where-Object { ($_.displayName).contains($inDCP) } | Sort-Object displayName + $SettCat=get-deviceconfigurationsettingscatalog | Where-Object { ($_.Name).contains($inDCP) } | Sort-Object Name + + +if(($DCPs) -or ($AdmTemp) -or ($SettCat)){ + write-host "These are the identified Configuration Profiles that would be tagged with $($ScopeTag.DisplayName)" + foreach($pol in $DCPs){write-host $pol.displayName -foregroundcolor Cyan} + if($AdmTemp){foreach($templ in $AdmTemp){write-host $templ.displayName -foregroundcolor Cyan}} + if($SettCat){foreach($templ in $SettCat){write-host $templ.Name -foregroundcolor Cyan}} + write-host "Are you sure you want to proceed (Y/N)?" + $answerDCP=read-host + } + else + { + Write-host "There were no Configuration profiles that matched your name pattern" -foregroundcolor Red + } - if($DCPs){ + if(($DCPs) -and (($answerDCP -eq "Y") -or ($answerDCP -eq "y"))){ foreach($Policy in $DCPs){ @@ -746,8 +1201,109 @@ if($Confirm -eq "y" -or $Confirm -eq "Y"){ } +if(($AdmTemp) -and (($answerDCP -eq "Y") -or ($answerDCP -eq "y"))){ + + foreach($Policy in $AdmTemp){ + + $DCP = Get-DeviceConfigurationAdminTemplates -id $Policy.id + + $DCP_DN = $DCP.displayName + + if($DCP.roleScopeTagIds){ + + if(!($DCP.roleScopeTagIds).contains("$ScopeTagId")){ + + $ST = @($DCP.roleScopeTagIds) + @("$ScopeTagId") + + $Result = Update-DeviceConfigurationAdminTemplate -id $DCP.id -ScopeTags $ST + + if($Result.displayname -eq $DCP.displayname){ + + Write-Host "Configuration Policy '$DCP_DN' patched with '$ScopeTag_DN' ScopeTag..." -ForegroundColor Green + + } + + } + + else { + + Write-Host "Scope Tag '$ScopeTag_DN' already assigned to '$DCP_DN'..." -ForegroundColor Red + + } + + } + + else { + + $ST = @("$ScopeTagId") + + $Result = Update-DeviceConfigurationAdminTemplate -id $Policy.id -ScopeTags $ST + + if($Result.displayname -eq $Policy.displayname){ + + Write-Host "Configuration Policy '$DCP_DN' patched with '$ScopeTag_DN' ScopeTag..." -ForegroundColor Green + + } + + } + + } + + } + Write-Host + +if(($SettCat) -and (($answerDCP -eq "Y") -or ($answerDCP -eq "y"))){ + + foreach($Policy in $SettCat){ + + $DCP = Get-DeviceConfigurationsettingscatalog -id $Policy.id + + $DCP_DN = $DCP.Name + + if($DCP.roleScopeTagIds){ + + if(!($DCP.roleScopeTagIds).contains("$ScopeTagId")){ + + $ST = @($DCP.roleScopeTagIds) + @("$ScopeTagId") + + $Result = Update-DeviceConfigurationsettingscatalog -id $DCP.id -ScopeTags $ST + + if($Result -eq ""){ + + Write-Host "Configuration Policy '$DCP_DN' patched with '$ScopeTag_DN' ScopeTag..." -ForegroundColor Green + + } + + } + + else { + + Write-Host "Scope Tag '$ScopeTag_DN' already assigned to '$DCP_DN'..." -ForegroundColor Red + + } + + } + + else { + + $ST = @("$ScopeTagId") + + $Result = Update-DeviceConfigurationsettingscatalog -id $DCP.id -ScopeTags $ST + + if($Result.name -eq $DCP.name){ + + Write-Host "Configuration Policy '$DCP_DN' patched with '$ScopeTag_DN' ScopeTag..." -ForegroundColor Green + + } + + } + + } + + } Write-Host + #endregion #################################################### @@ -758,7 +1314,7 @@ if($Confirm -eq "y" -or $Confirm -eq "Y"){ else { - Write-Host "No Scope Tags configured..." -ForegroundColor Red + Write-Host "No Scope Tags found with that name..." -ForegroundColor Red } @@ -766,8 +1322,8 @@ if($Confirm -eq "y" -or $Confirm -eq "Y"){ else { - Write-Host "Addition of Scope Tags to all Configuration and Compliance Policies was cancelled..." -ForegroundColor Yellow + Write-Host "Addition of Scope Tags to all Configuration and Compliance Policies was cancelled" } -Write-Host \ No newline at end of file +Write-Host