diff --git a/.gitignore b/.gitignore index 3e759b7..13a9b2e 100644 --- a/.gitignore +++ b/.gitignore @@ -221,7 +221,7 @@ ClientBin/ *.publishsettings orleans.codegen.cs -# Including strong name files can present a security risk +# Including strong name files can present a security risk # (https://github.com/github/gitignore/pull/2483#issue-259490424) #*.snk @@ -317,7 +317,7 @@ __pycache__/ # OpenCover UI analysis results OpenCover/ -# Azure Stream Analytics local run output +# Azure Stream Analytics local run output ASALocalRun/ # MSBuild Binary and Structured Log @@ -326,5 +326,5 @@ ASALocalRun/ # NVidia Nsight GPU debugger configuration file *.nvuser -# MFractors (Xamarin productivity tool) working folder +# MFractors (Xamarin productivity tool) working folder .mfractor/ diff --git a/ENT/Import-ENT-DeviceCompliancePolicies.ps1 b/ENT/Import-ENT-DeviceCompliancePolicies.ps1 index 00ef5fb..b2d8810 100644 --- a/ENT/Import-ENT-DeviceCompliancePolicies.ps1 +++ b/ENT/Import-ENT-DeviceCompliancePolicies.ps1 @@ -7,7 +7,7 @@ See LICENSE in the project root for license information. #> $ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path -$ImportPath = $ScriptDir + "\JSON\DeviceCompliance" +$ImportPath = $ScriptDir + '\JSON\DeviceCompliance' #################################################### @@ -26,7 +26,7 @@ Authenticates you with the Graph API interface NAME: Test-MgAuth #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -34,21 +34,21 @@ NAME: Test-MgAuth $User ) - $userUpn = New-Object "System.Net.Mail.MailAddress" -ArgumentList $User + $userUpn = New-Object 'System.Net.Mail.MailAddress' -ArgumentList $User $tenant = $userUpn.Host - Write-Host "Checking for Microsoft Graph module..." + Write-Host 'Checking for Microsoft Graph module...' - $MgModule = Get-Module -Name "Microsoft.Graph" -ListAvailable + $MgModule = Get-Module -Name 'Microsoft.Graph' -ListAvailable if ($null -eq $MgModule) { - write-host - write-host "Microsoft Graph Powershell module not installed..." -f Red - write-host "Install by running 'Install-Module Microsoft.Graph' or 'Install-Module Microsoft.Graph' from an elevated PowerShell prompt" -f Yellow - write-host "Script can't continue..." -f Red - write-host - + Write-Host + Write-Host 'Microsoft Graph Powershell module not installed...' -f Red + Write-Host "Install by running 'Install-Module Microsoft.Graph' or 'Install-Module Microsoft.Graph' from an elevated PowerShell prompt" -f Yellow + Write-Host "Script can't continue..." -f Red + Write-Host + } $scopes = @() @@ -56,20 +56,20 @@ NAME: Test-MgAuth ######################################### # Directory related scopes # ######################################### - $scopes += @("Device.Read.All", - "User.Read.All", - "GroupMember.ReadWrite.All", - "Group.ReadWrite.All", - "Directory.ReadWrite.All") + $scopes += @('Device.Read.All', + 'User.Read.All', + 'GroupMember.ReadWrite.All', + 'Group.ReadWrite.All', + 'Directory.ReadWrite.All') ######################################### # Device Management scopes # ######################################### - $scopes += @("DeviceManagementConfiguration.ReadWrite.All", - "DeviceManagementServiceConfig.ReadWrite.All", - "DeviceManagementRBAC.ReadWrite.All", - "DeviceManagementManagedDevices.ReadWrite.All", - "DeviceManagementApps.ReadWrite.All") + $scopes += @('DeviceManagementConfiguration.ReadWrite.All', + 'DeviceManagementServiceConfig.ReadWrite.All', + 'DeviceManagementRBAC.ReadWrite.All', + 'DeviceManagementManagedDevices.ReadWrite.All', + 'DeviceManagementApps.ReadWrite.All') #$clientId = "d1ddf0e4-d672-4dae-b554-9d5bdfd93547" @@ -84,11 +84,11 @@ NAME: Test-MgAuth $ctx = Get-MgContext $org = Get-MgOrganization - $domains = $org.VerifiedDomains | select-object -ExpandProperty Name + $domains = $org.VerifiedDomains | Select-Object -ExpandProperty Name if ($ctx.Account.ToLower() -ne $userUpn.Address.ToLower() -or ($ctx.TenantId -ne $org.Id) -or $domains -notcontains $tenant) { - write-host "Unable to verify tenant or account" -f Red + Write-Host 'Unable to verify tenant or account' -f Red Disconnect-MgGraph - throw "Unable to continue due to validation" + throw 'Unable to continue due to validation' } # $authHeader = @{ @@ -100,9 +100,9 @@ NAME: Test-MgAuth # return $authHeader } catch { - write-host $_.Exception.Message -f Red - write-host $_.Exception.ItemName -f Red - write-host + Write-Host $_.Exception.Message -f Red + Write-Host $_.Exception.ItemName -f Red + Write-Host break } @@ -124,44 +124,44 @@ Function Add-DeviceCompliancePolicy() { .NOTES NAME: Add-DeviceCompliancePolicy #> - - [cmdletbinding()] - + + [CmdletBinding()] + param ( $JSON ) - - $graphApiVersion = "Beta" - $Resource = "deviceManagement/deviceCompliancePolicies" - + + $graphApiVersion = 'Beta' + $Resource = 'deviceManagement/deviceCompliancePolicies' + try { - - if ($JSON -eq "" -or $null -eq $JSON) { - - write-host "No JSON specified, please specify valid JSON for the iOS Policy..." -f Red - + + if ([string]::IsNullOrWhiteSpace($JSON)) { + + Write-Host 'No JSON specified, please specify valid JSON for the iOS Policy...' -f Red + } - + else { - - Test-JSON -JSON $JSON - + + Test-Json -Json $JSON + $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)" - Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType "application/json" + Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType 'application/json' } } catch { $ex = $_.Exception - + Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break } } - + #################################################### @@ -179,7 +179,7 @@ Returns all users registered with Azure AD NAME: Get-AADGroup #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -189,11 +189,11 @@ NAME: Get-AADGroup ) # Defining Variables - $graphApiVersion = "v1.0" - $Group_resource = "groups" + $graphApiVersion = 'v1.0' + $Group_resource = 'groups' # pseudo-group identifiers for all users and all devices - [string]$AllUsers = "acacacac-9df4-4c7d-9d50-4ef0226f57a9" - [string]$AllDevices = "adadadad-808e-44e2-905a-0b7873a8a531" + [string]$AllUsers = 'acacacac-9df4-4c7d-9d50-4ef0226f57a9' + [string]$AllDevices = 'adadadad-808e-44e2-905a-0b7873a8a531' try { @@ -201,14 +201,14 @@ NAME: Get-AADGroup $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)?`$filter=id eq '$id'" switch ( $id ) { - $AllUsers { $grp = [PSCustomObject]@{ displayName = "All users" }; $grp } - $AllDevices { $grp = [PSCustomObject]@{ displayName = "All devices" }; $grp } + $AllUsers { $grp = [PSCustomObject]@{ displayName = 'All users' }; $grp } + $AllDevices { $grp = [PSCustomObject]@{ displayName = 'All devices' }; $grp } default { (Invoke-MgGraphRequest -Uri $uri -Method Get).Value } } - + } - elseif ($GroupName -eq "" -or $null -eq $GroupName) { + elseif ([string]::IsNullOrWhiteSpace($GroupName)) { $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)" (Invoke-MgGraphRequest -Uri $uri -Method Get).Value @@ -234,7 +234,7 @@ NAME: Get-AADGroup $GID = $Group.id $Group.displayName - write-host + Write-Host $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)/$GID/Members" (Invoke-MgGraphRequest -Uri $uri -Method Get).Value @@ -250,11 +250,11 @@ NAME: Get-AADGroup catch { $ex = $_.Exception - + Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break } @@ -279,37 +279,37 @@ Function Get-DeviceCompliancePolicy() { .NOTES NAME: Get-DeviceCompliancePolicy #> - - [cmdletbinding()] - + + [CmdletBinding()] + param ( $Name ) - $graphApiVersion = "Beta" - $Resource = "deviceManagement/deviceCompliancePolicies" - + $graphApiVersion = 'Beta' + $Resource = 'deviceManagement/deviceCompliancePolicies' + try { - + $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)" - (Invoke-MgGraphRequest -Uri $uri -Method Get).Value | Where-Object { ($_.'@odata.type').contains("windows10CompliancePolicy") -and ($_.'displayName').contains($Name) } - + (Invoke-MgGraphRequest -Uri $uri -Method Get).Value | Where-Object { ($_.'@odata.type').contains('windows10CompliancePolicy') -and ($_.'displayName').contains($Name) } + } - + catch { - + $ex = $_.Exception - + Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break - + } - + } - + #################################################### @@ -327,34 +327,34 @@ Function Add-DeviceCompliancePolicyAssignment() { .NOTES NAME: Add-DeviceCompliancePolicyAssignment #> - - [cmdletbinding()] - + + [CmdletBinding()] + param ( $CompliancePolicyId, $ComplianceAssignments ) - - $graphApiVersion = "v1.0" + + $graphApiVersion = 'v1.0' $Resource = "deviceManagement/deviceCompliancePolicies/$CompliancePolicyId/assign" - + try { - + if (!$CompliancePolicyId) { - - write-host "No Compliance Policy Id specified, specify a valid Compliance Policy Id" -f Red + + Write-Host 'No Compliance Policy Id specified, specify a valid Compliance Policy Id' -f Red break - + } - + if (!$ComplianceAssignments) { - write-host "No Target Group Id specified, specify a valid Target Group Id" -f Red + Write-Host 'No Target Group Id specified, specify a valid Target Group Id' -f Red break - + } - + $JSON = @" { @@ -367,24 +367,24 @@ Function Add-DeviceCompliancePolicyAssignment() { Write-Output $JSON $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)" - Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType "application/json" - - + Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType 'application/json' + + } - + catch { - + $ex = $_.Exception - + Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break } - + } - + #################################################### Function Test-JSON() { @@ -422,7 +422,7 @@ NAME: Test-AuthHeader } if (!$validJson) { - + Write-Host "Provided JSON isn't in valid JSON format" -f Red break @@ -434,11 +434,11 @@ NAME: Test-AuthHeader #region Authentication -write-host +Write-Host -if ($null -eq $User -or $User -eq "") { +if ([string]::IsNullOrWhiteSpace($User)) { - $User = Read-Host -Prompt "Please specify your user principal name for Azure Authentication" + $User = Read-Host -Prompt 'Please specify your user principal name for Azure Authentication' Write-Host } @@ -463,10 +463,10 @@ if (!(Test-Path "$ImportPath")) { #################################################### -Get-ChildItem $ImportPath -filter *.json | -Foreach-object { +Get-ChildItem $ImportPath -Filter *.json | +ForEach-Object { - $JSON_Data = Get-Content $_.FullName | Where-Object { $_ -notmatch "scheduledActionConfigurations@odata.context" } + $JSON_Data = Get-Content $_.FullName | Where-Object { $_ -notmatch 'scheduledActionConfigurations@odata.context' } # Excluding entries that are not required - id,createdDateTime,lastModifiedDateTime,version $JSON_Convert = $JSON_Data | ConvertFrom-Json | Select-Object -Property * -ExcludeProperty id, createdDateTime, lastModifiedDateTime, scheduledActionsForRule@odata.context @@ -483,7 +483,7 @@ Foreach-object { # Adding Scheduled Actions Rule to JSON - #$scheduledActionsForRule = '"scheduledActionsForRule":[{"ruleName":"PasswordRequired","scheduledActionConfigurations":[{"actionType":"block","gracePeriodHours":0,"notificationTemplateId":"","notificationMessageCCList":[]}]}]' + #$scheduledActionsForRule = '"scheduledActionsForRule":[{"ruleName":"PasswordRequired","scheduledActionConfigurations":[{"actionType":"block","gracePeriodHours":0,"notificationTemplateId":"","notificationMessageCCList":[]}]}]' #$JSON_Output = $JSON_Output.trimend("}") @@ -491,12 +491,12 @@ Foreach-object { # Joining the JSON together #$JSON_Output = $JSON_Output + $scheduledActionsForRule + "`r`n" + "}" - - write-host - write-host "Device Configuration Policy '$DisplayName' Found..." -ForegroundColor Yellow - write-host + + Write-Host + Write-Host "Device Configuration Policy '$DisplayName' Found..." -ForegroundColor Yellow + Write-Host $JSON_Output - write-host + Write-Host Write-Host "Adding Device Configuration Policy '$DisplayName'" -ForegroundColor Yellow Add-DeviceCompliancePolicy -JSON $JSON_Output @@ -511,16 +511,14 @@ Foreach-object { $ComplianceAssignments = @() - foreach ($AADGroup in $AADGroups ) - - { - Write-Host "AAD Group Name:" $AADGroup.groupId -ForegroundColor Yellow - Write-Host "Assignment Type:" $AADGroup."@OData.type" -ForegroundColor Yellow + foreach ($AADGroup in $AADGroups ) { + Write-Host 'AAD Group Name:' $AADGroup.groupId -ForegroundColor Yellow + Write-Host 'Assignment Type:' $AADGroup.'@OData.type' -ForegroundColor Yellow $TargetGroupId = (Get-AADGroup -GroupName $AADGroup.groupid) $TargetGroupId = $TargetGroupId.id - Write-Host "Included Group ID:" $TargetGroupID -ForegroundColor Yellow + Write-Host 'Included Group ID:' $TargetGroupID -ForegroundColor Yellow - $Assignment = $AADGroup."@OData.type" + $Assignment = $AADGroup.'@OData.type' $GroupAdd = @" { "target": { @@ -530,17 +528,16 @@ Foreach-object { }, "@ - + $ComplianceAssignments += $GroupAdd } - + Add-DeviceCompliancePolicyAssignment -ComplianceAssignments $ComplianceAssignments -CompliancePolicyId $CompliancePolicyId - - } - else - { - write-host "Device Compliance Policy:" $JSON_Convert.displayName "has already been created" -ForegroundColor Yellow } -} + else { + Write-Host 'Device Compliance Policy:' $JSON_Convert.displayName 'has already been created' -ForegroundColor Yellow + } + +} diff --git a/ENT/Import-ENT-DeviceConfigScript.ps1 b/ENT/Import-ENT-DeviceConfigScript.ps1 index f5b212f..bf14ef8 100644 --- a/ENT/Import-ENT-DeviceConfigScript.ps1 +++ b/ENT/Import-ENT-DeviceConfigScript.ps1 @@ -7,7 +7,7 @@ See LICENSE in the project root for license information. #> $ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path -$ImportPath = $ScriptDir+"\Scripts\ENT-DeviceConfig.ps1" +$ImportPath = $ScriptDir + '\Scripts\ENT-DeviceConfig.ps1' #################################################### @@ -25,7 +25,7 @@ Authenticates you with the Graph API interface NAME: Get-AuthToken #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -33,27 +33,27 @@ NAME: Get-AuthToken $User ) - $userUpn = New-Object "System.Net.Mail.MailAddress" -ArgumentList $User + $userUpn = New-Object 'System.Net.Mail.MailAddress' -ArgumentList $User $tenant = $userUpn.Host - Write-Host "Checking for AzureADPreview module..." + Write-Host 'Checking for AzureADPreview module...' - $AadModule = Get-Module -Name "AzureADPreview" -ListAvailable + $AadModule = Get-Module -Name 'AzureADPreview' -ListAvailable if ($AadModule -eq $null) { - Write-Host "AzureAD PowerShell module not found, looking for AzureADPreview" - $AadModule = Get-Module -Name "AzureADPreview" -ListAvailable + Write-Host 'AzureAD PowerShell module not found, looking for AzureADPreview' + $AadModule = Get-Module -Name 'AzureADPreview' -ListAvailable } if ($AadModule -eq $null) { - write-host - write-host "AzureAD Powershell module not installed..." -f Red - write-host "Install by running 'Install-Module AzureAD' or 'Install-Module AzureADPreview' from an elevated PowerShell prompt" -f Yellow - write-host "Script can't continue..." -f Red - write-host + Write-Host + Write-Host 'AzureAD Powershell module not installed...' -f Red + Write-Host "Install by running 'Install-Module AzureAD' or 'Install-Module AzureADPreview' from an elevated PowerShell prompt" -f Yellow + Write-Host "Script can't continue..." -f Red + Write-Host exit } @@ -62,27 +62,27 @@ NAME: Get-AuthToken if ($AadModule.count -gt 1) { - $Latest_Version = ($AadModule | select version | Sort-Object)[-1] + $Latest_Version = ($AadModule | Select-Object version | Sort-Object)[-1] - $aadModule = $AadModule | ? { $_.version -eq $Latest_Version.version } + $aadModule = $AadModule | Where-Object { $_.version -eq $Latest_Version.version } # Checking if there are multiple versions of the same module found if ($AadModule.count -gt 1) { - $aadModule = $AadModule | select -Unique + $aadModule = $AadModule | Select-Object -Unique } - $adal = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.dll" - $adalforms = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll" + $adal = Join-Path $AadModule.ModuleBase 'Microsoft.IdentityModel.Clients.ActiveDirectory.dll' + $adalforms = Join-Path $AadModule.ModuleBase 'Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll' } else { - $adal = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.dll" - $adalforms = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll" + $adal = Join-Path $AadModule.ModuleBase 'Microsoft.IdentityModel.Clients.ActiveDirectory.dll' + $adalforms = Join-Path $AadModule.ModuleBase 'Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll' } @@ -90,24 +90,24 @@ NAME: Get-AuthToken [System.Reflection.Assembly]::LoadFrom($adalforms) | Out-Null - $clientId = "d1ddf0e4-d672-4dae-b554-9d5bdfd93547" + $clientId = 'd1ddf0e4-d672-4dae-b554-9d5bdfd93547' - $redirectUri = "urn:ietf:wg:oauth:2.0:oob" + $redirectUri = 'urn:ietf:wg:oauth:2.0:oob' - $resourceAppIdURI = "https://graph.microsoft.com" + $resourceAppIdURI = 'https://graph.microsoft.com' $authority = "https://login.microsoftonline.com/$Tenant" try { - $authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority + $authContext = New-Object 'Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext' -ArgumentList $authority # https://msdn.microsoft.com/en-us/library/azure/microsoft.identitymodel.clients.activedirectory.promptbehavior.aspx # Change the prompt behaviour to force credentials each time: Auto, Always, Never, RefreshSession - $platformParameters = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.PlatformParameters" -ArgumentList "Auto" + $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.UserIdentifier' -ArgumentList ($User, 'OptionalDisplayableId') $authResult = $authContext.AcquireTokenAsync($resourceAppIdURI, $clientId, $redirectUri, $platformParameters, $userId).Result @@ -119,7 +119,7 @@ NAME: Get-AuthToken $authHeader = @{ 'Content-Type' = 'application/json' - 'Authorization' = "Bearer " + $authResult.AccessToken + 'Authorization' = 'Bearer ' + $authResult.AccessToken 'ExpiresOn' = $authResult.ExpiresOn } @@ -130,7 +130,7 @@ NAME: Get-AuthToken else { Write-Host - Write-Host "Authorization Access Token is null, please re-run authentication..." -ForegroundColor Red + Write-Host 'Authorization Access Token is null, please re-run authentication...' -ForegroundColor Red Write-Host break @@ -140,9 +140,9 @@ NAME: Get-AuthToken catch { - write-host $_.Exception.Message -f Red - write-host $_.Exception.ItemName -f Red - write-host + Write-Host $_.Exception.Message -f Red + Write-Host $_.Exception.ItemName -f Red + Write-Host break } @@ -165,7 +165,7 @@ Adds a device management script from a URL in Intune .NOTES NAME: Add-DeviceManagementScript #> - [cmdletbinding()] + [CmdletBinding()] Param ( # Path or URL to Powershell-script to add to Intune [Parameter(Mandatory = $true)] @@ -178,7 +178,7 @@ NAME: Add-DeviceManagementScript [switch][bool]$URL = $false ) if ($URL -eq $true) { - $FileName = $File -split "/" + $FileName = $File -split '/' $FileName = $FileName[-1] $OutFile = "$env:TEMP\$FileName" try { @@ -201,7 +201,7 @@ NAME: Add-DeviceManagementScript } $FileName = Get-Item $File | Select-Object -ExpandProperty Name } - $B64File = [System.Convert]::ToBase64String([System.IO.File]::ReadAllBytes("$File")); + $B64File = [System.Convert]::ToBase64String([System.IO.File]::ReadAllBytes("$File")) if ($URL -eq $true) { Remove-Item $File -Force @@ -223,13 +223,13 @@ NAME: Add-DeviceManagementScript } "@ - $graphApiVersion = "Beta" - $DMS_resource = "deviceManagement/deviceManagementScripts" + $graphApiVersion = 'Beta' + $DMS_resource = 'deviceManagement/deviceManagementScripts' Write-Verbose "Resource: $DMS_resource" try { $uri = "https://graph.microsoft.com/$graphApiVersion/$DMS_resource" - Invoke-RestMethod -Uri $uri -Headers $authToken -Method Post -Body $JSON -ContentType "application/json" + Invoke-RestMethod -Uri $uri -Headers $authToken -Method Post -Body $JSON -ContentType 'application/json' } catch { @@ -239,10 +239,10 @@ NAME: Add-DeviceManagementScript $reader = New-Object System.IO.StreamReader($errorResponse) $reader.BaseStream.Position = 0 $reader.DiscardBufferedData() - $responseBody = $reader.ReadToEnd(); + $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 + Write-Host break } @@ -264,7 +264,7 @@ Adds a device configuration policy assignment in Intune NAME: Add-DeviceConfigurationPolicyAssignment #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -272,21 +272,21 @@ NAME: Add-DeviceConfigurationPolicyAssignment $TargetGroupId ) - $graphApiVersion = "Beta" + $graphApiVersion = 'Beta' $Resource = "deviceManagement/deviceManagementScripts/$ScriptId/assign" try { if (!$ScriptId) { - write-host "No Script Policy Id specified, specify a valid Script Policy Id" -f Red + Write-Host 'No Script Policy Id specified, specify a valid Script Policy Id' -f Red break } if (!$TargetGroupId) { - write-host "No Target Group Id specified, specify a valid Target Group Id" -f Red + Write-Host 'No Target Group Id specified, specify a valid Target Group Id' -f Red break } @@ -304,7 +304,7 @@ NAME: Add-DeviceConfigurationPolicyAssignment "@ $uri = "https://graph.microsoft.com/$graphApiVersion/$Resource" - Invoke-RestMethod -Uri $uri -Headers $authToken -Method Post -Body $JSON -ContentType "application/json" + Invoke-RestMethod -Uri $uri -Headers $authToken -Method Post -Body $JSON -ContentType 'application/json' } @@ -315,10 +315,10 @@ NAME: Add-DeviceConfigurationPolicyAssignment $reader = New-Object System.IO.StreamReader($errorResponse) $reader.BaseStream.Position = 0 $reader.DiscardBufferedData() - $responseBody = $reader.ReadToEnd(); + $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 + Write-Host break } @@ -340,7 +340,7 @@ Returns all users registered with Azure AD NAME: Get-AADGroup #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -350,8 +350,8 @@ NAME: Get-AADGroup ) # Defining Variables - $graphApiVersion = "v1.0" - $Group_resource = "groups" + $graphApiVersion = 'v1.0' + $Group_resource = 'groups' try { @@ -362,7 +362,7 @@ NAME: Get-AADGroup } - elseif ($GroupName -eq "" -or $GroupName -eq $null) { + elseif ([string]::IsNullOrWhiteSpace($GroupName)) { $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)" (Invoke-RestMethod -Uri $uri -Headers $authToken -Method Get).Value @@ -388,7 +388,7 @@ NAME: Get-AADGroup $GID = $Group.id $Group.displayName - write-host + Write-Host $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)/$GID/Members" (Invoke-RestMethod -Uri $uri -Headers $authToken -Method Get).Value @@ -406,10 +406,10 @@ NAME: Get-AADGroup $reader = New-Object System.IO.StreamReader($errorResponse) $reader.BaseStream.Position = 0 $reader.DiscardBufferedData() - $responseBody = $reader.ReadToEnd(); + $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 + Write-Host break } @@ -421,7 +421,7 @@ NAME: Get-AADGroup #region Authentication -write-host +Write-Host # Checking if authToken exists before running authentication if ($global:authToken) { @@ -434,14 +434,14 @@ if ($global:authToken) { if ($TokenExpires -le 0) { - write-host "Authentication Token expired" $TokenExpires "minutes ago" -ForegroundColor Yellow - write-host + Write-Host 'Authentication Token expired' $TokenExpires 'minutes ago' -ForegroundColor Yellow + Write-Host # Defining User Principal Name if not present - if ($User -eq $null -or $User -eq "") { + if ([string]::IsNullOrWhiteSpace($User)) { - $User = Read-Host -Prompt "Please specify your user principal name for Azure Authentication" + $User = Read-Host -Prompt 'Please specify your user principal name for Azure Authentication' Write-Host } @@ -455,9 +455,9 @@ if ($global:authToken) { else { - if ($User -eq $null -or $User -eq "") { + if ([string]::IsNullOrWhiteSpace($User)) { - $User = Read-Host -Prompt "Please specify your user principal name for Azure Authentication" + $User = Read-Host -Prompt 'Please specify your user principal name for Azure Authentication' Write-Host } @@ -474,12 +474,12 @@ else { # Setting application AAD Group to assign PowerShell scripts #$AADGroup = Read-Host -Prompt "Enter the Azure AD Group name where PowerShell scripts will be assigned" -$AADGroup = "Enterprise Workstations" +$AADGroup = 'Enterprise Workstations' $TargetGroupId = (Get-AADGroup -GroupName "$AADGroup").id -if ($TargetGroupId -eq $null -or $TargetGroupId -eq "") { +if ([string]::IsNullOrWhiteSpace($TargetGroupId)) { Write-Host "AAD Group - '$AADGroup' doesn't exist, please specify a valid AAD Group..." -ForegroundColor Red Write-Host @@ -489,13 +489,13 @@ if ($TargetGroupId -eq $null -or $TargetGroupId -eq "") { #################################################### -Write-Host "Adding Device Configuration Script from " $ImportPath -ForegroundColor Green +Write-Host 'Adding Device Configuration Script from ' $ImportPath -ForegroundColor Green -$Create_Local_Script = Add-DeviceManagementScript -File $ImportPath -Description "Enterprise Device Config script" +$Create_Local_Script = Add-DeviceManagementScript -File $ImportPath -Description 'Enterprise Device Config script' -Write-Host "Device Management Script created as" $Create_Local_Script.id -write-host -write-host "Assigning Device Management Script to AAD Group '$AADGroup'" -f Cyan +Write-Host 'Device Management Script created as' $Create_Local_Script.id +Write-Host +Write-Host "Assigning Device Management Script to AAD Group '$AADGroup'" -f Cyan $Assign_Local_Script = Add-DeviceManagementScriptAssignment -ScriptId $Create_Local_Script.id -TargetGroupId $TargetGroupId diff --git a/ENT/Import-ENT-DeviceConfiguration.ps1 b/ENT/Import-ENT-DeviceConfiguration.ps1 index cce22b4..0ea258f 100644 --- a/ENT/Import-ENT-DeviceConfiguration.ps1 +++ b/ENT/Import-ENT-DeviceConfiguration.ps1 @@ -26,7 +26,7 @@ Authenticates you with the Graph API interface NAME: Test-MgAuth #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -48,7 +48,7 @@ NAME: Test-MgAuth write-host "Install by running 'Install-Module Microsoft.Graph' or 'Install-Module Microsoft.Graph' from an elevated PowerShell prompt" -f Yellow write-host "Script can't continue..." -f Red write-host - + } $scopes = @() @@ -56,19 +56,19 @@ NAME: Test-MgAuth ######################################### # Directory related scopes # ######################################### - $scopes += @("Device.Read.All", - "User.Read.All", - "GroupMember.ReadWrite.All", - "Group.ReadWrite.All", + $scopes += @("Device.Read.All", + "User.Read.All", + "GroupMember.ReadWrite.All", + "Group.ReadWrite.All", "Directory.ReadWrite.All") ######################################### # Device Management scopes # ######################################### - $scopes += @("DeviceManagementConfiguration.ReadWrite.All", - "DeviceManagementServiceConfig.ReadWrite.All", - "DeviceManagementRBAC.ReadWrite.All", - "DeviceManagementManagedDevices.ReadWrite.All", + $scopes += @("DeviceManagementConfiguration.ReadWrite.All", + "DeviceManagementServiceConfig.ReadWrite.All", + "DeviceManagementRBAC.ReadWrite.All", + "DeviceManagementManagedDevices.ReadWrite.All", "DeviceManagementApps.ReadWrite.All") @@ -125,7 +125,7 @@ Adds a device configuration policy in Intune NAME: Add-DeviceConfigurationPolicy #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -138,7 +138,7 @@ NAME: Add-DeviceConfigurationPolicy try { - if ($JSON -eq "" -or $null -eq $JSON) { + if ([string]::IsNullOrWhiteSpace($JSON)) { write-host "No JSON specified, please specify valid JSON for the Policy..." -f Red @@ -156,7 +156,7 @@ NAME: Add-DeviceConfigurationPolicy catch { $ex = $_.Exception - + Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" @@ -183,7 +183,7 @@ Adds a device configuration policy assignment in Intune NAME: Add-DeviceConfigurationPolicyAssignment #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -194,7 +194,7 @@ NAME: Add-DeviceConfigurationPolicyAssignment $graphApiVersion = "Beta" $Resource = "deviceManagement/deviceConfigurations/$ConfigurationPolicyId/assignments" - + try { if (!$ConfigurationPolicyId) { @@ -208,7 +208,7 @@ NAME: Add-DeviceConfigurationPolicyAssignment write-host "No Target Group Id specified, specify a valid Target Group Id" -f Red break - + } if (!$Assignment) { @@ -232,11 +232,11 @@ NAME: Add-DeviceConfigurationPolicyAssignment $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)" Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType "application/json" } - + catch { $ex = $_.Exception - + Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" @@ -264,7 +264,7 @@ Returns any device configuration policies configured in Intune NAME: Get-DeviceConfigurationPolicy #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -295,7 +295,7 @@ NAME: Get-DeviceConfigurationPolicy catch { $ex = $_.Exception - + Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" @@ -322,7 +322,7 @@ Returns all users registered with Azure AD NAME: Get-AADGroup #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -348,10 +348,10 @@ NAME: Get-AADGroup $AllDevices { $grp = [PSCustomObject]@{ displayName = "All devices" }; $grp } default { (Invoke-MgGraphRequest -Uri $uri -Method Get).Value } } - + } - elseif ($GroupName -eq "" -or $null -eq $GroupName) { + elseif ([string]::IsNullOrWhiteSpace($GroupName)) { $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)" (Invoke-MgGraphRequest -Uri $uri -Method Get).Value @@ -393,7 +393,7 @@ NAME: Get-AADGroup catch { $ex = $_.Exception - + Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" @@ -440,7 +440,7 @@ NAME: Test-AuthHeader } if (!$validJson) { - + Write-Host "Provided JSON isn't in valid JSON format" -f Red break @@ -454,7 +454,7 @@ NAME: Test-AuthHeader write-host -if ($null -eq $User -or $User -eq "") { +if ([string]::IsNullOrWhiteSpace($User)) { $User = Read-Host -Prompt "Please specify your user principal name for Azure Authentication" Write-Host @@ -510,7 +510,7 @@ Foreach-object { If ($DuplicateDCP -eq $null) { $JSON_Output = $JSON_Convert | ConvertTo-Json -Depth 5 - + write-host write-host "Device Configuration Policy '$DisplayName' Found..." -ForegroundColor Yellow write-host @@ -524,33 +524,33 @@ Foreach-object { $DeviceConfigID = $DeviceConfigs.id - Write-Host "Device ConfigID '$DeviceConfigID'" -ForegroundColor Yellow + Write-Host "Device ConfigID '$DeviceConfigID'" -ForegroundColor Yellow Write-Host $AADGroups = $JSON_Convert.assignments.target - foreach ($AADGroup in $AADGroups ) + foreach ($AADGroup in $AADGroups ) { Write-Host "AAD Group Name:" $AADGroup.groupId -ForegroundColor Yellow Write-Host "Assignment Type:" $AADGroup."@OData.type" -ForegroundColor Yellow - + $TargetGroupId = (Get-AADGroup -GroupName $AADGroup.groupid) Write-Host "Included Group ID:" $TargetGroupID.Id -ForegroundColor Yellow - Add-DeviceConfigurationPolicyAssignment -ConfigurationPolicyId $DeviceConfigID -TargetGroupId $TargetGroupId.id -Assignment $AADGroup."@OData.type" + Add-DeviceConfigurationPolicyAssignment -ConfigurationPolicyId $DeviceConfigID -TargetGroupId $TargetGroupId.id -Assignment $AADGroup."@OData.type" } - + # Create exclude Group - + <#$ShortName = $JSON_Convert.displayName -replace "PAW-Global-2009-Intune-Configuration-", '' - $ExcludeGroup = "PAW-"+$ShortName+"-Exclude-Device" + $ExcludeGroup = "PAW-"+$ShortName+"-Exclude-Device" If (Get-AzureADGroup -SearchString $ExcludeGroup) { Write-Host Write-Host "AAD group" $ExcludeGroup "already exists!" -f Yellow Write-Host } Else { - + $MailNickName = $ShortName+"-G" - + try { $ExcludeTargetGroup = New-AzureADGroup -DisplayName $ExcludeGroup -Description $ExcludeGroup"-Group" -MailEnabled $false -SecurityEnabled $true -MailNickName $MailNickName @@ -563,13 +563,13 @@ Foreach-object { Write-Host } - } - + } + Write-Host "Excluded Group ID" $ExcludeTargetGroup.objectid Add-DeviceConfigurationPolicyAssignment -ConfigurationPolicyId $DeviceConfigID -TargetGroupId $ExcludeTargetGroup.objectid -Assignment "exclusionGroupAssignmentTarget" #> } - + else { write-host "Device Configuration Profile:" $JSON_Convert.displayName "has already been created" -ForegroundColor Yellow } diff --git a/ENT/Import-ENT-DeviceConfigurationADMX.ps1 b/ENT/Import-ENT-DeviceConfigurationADMX.ps1 index 5105233..bf5cc36 100644 --- a/ENT/Import-ENT-DeviceConfigurationADMX.ps1 +++ b/ENT/Import-ENT-DeviceConfigurationADMX.ps1 @@ -10,13 +10,13 @@ param ( #Change Conditional Access State, default is disabled #Options: enabled, disabled, enabledForReportingButNotEnforced - [String]$AADGroup = "Privileged Workstations" - + [String]$AADGroup = 'Privileged Workstations' + ) #$AADGroup = "PAW-Global-Devices" $ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path -$ImportPath = $ScriptDir + "\JSON\DeviceConfigurationADMX" +$ImportPath = $ScriptDir + '\JSON\DeviceConfigurationADMX' function Test-MgAuth { @@ -32,7 +32,7 @@ Authenticates you with the Graph API interface NAME: Test-MgAuth #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -40,21 +40,21 @@ NAME: Test-MgAuth $User ) - $userUpn = New-Object "System.Net.Mail.MailAddress" -ArgumentList $User + $userUpn = New-Object 'System.Net.Mail.MailAddress' -ArgumentList $User $tenant = $userUpn.Host - Write-Host "Checking for Microsoft Graph module..." + Write-Host 'Checking for Microsoft Graph module...' - $MgModule = Get-Module -Name "Microsoft.Graph" -ListAvailable + $MgModule = Get-Module -Name 'Microsoft.Graph' -ListAvailable if ($null -eq $MgModule) { - write-host - write-host "Microsoft Graph Powershell module not installed..." -f Red - write-host "Install by running 'Install-Module Microsoft.Graph' or 'Install-Module Microsoft.Graph' from an elevated PowerShell prompt" -f Yellow - write-host "Script can't continue..." -f Red - write-host - + Write-Host + Write-Host 'Microsoft Graph Powershell module not installed...' -f Red + Write-Host "Install by running 'Install-Module Microsoft.Graph' or 'Install-Module Microsoft.Graph' from an elevated PowerShell prompt" -f Yellow + Write-Host "Script can't continue..." -f Red + Write-Host + } $scopes = @() @@ -62,20 +62,20 @@ NAME: Test-MgAuth ######################################### # Directory related scopes # ######################################### - $scopes += @("Device.Read.All", - "User.Read.All", - "GroupMember.ReadWrite.All", - "Group.ReadWrite.All", - "Directory.ReadWrite.All") + $scopes += @('Device.Read.All', + 'User.Read.All', + 'GroupMember.ReadWrite.All', + 'Group.ReadWrite.All', + 'Directory.ReadWrite.All') ######################################### # Device Management scopes # ######################################### - $scopes += @("DeviceManagementConfiguration.ReadWrite.All", - "DeviceManagementServiceConfig.ReadWrite.All", - "DeviceManagementRBAC.ReadWrite.All", - "DeviceManagementManagedDevices.ReadWrite.All", - "DeviceManagementApps.ReadWrite.All") + $scopes += @('DeviceManagementConfiguration.ReadWrite.All', + 'DeviceManagementServiceConfig.ReadWrite.All', + 'DeviceManagementRBAC.ReadWrite.All', + 'DeviceManagementManagedDevices.ReadWrite.All', + 'DeviceManagementApps.ReadWrite.All') #$clientId = "d1ddf0e4-d672-4dae-b554-9d5bdfd93547" @@ -90,11 +90,11 @@ NAME: Test-MgAuth $ctx = Get-MgContext $org = Get-MgOrganization - $domains = $org.VerifiedDomains | select-object -ExpandProperty Name + $domains = $org.VerifiedDomains | Select-Object -ExpandProperty Name if ($ctx.Account.ToLower() -ne $userUpn.Address.ToLower() -or ($ctx.TenantId -ne $org.Id) -or $domains -notcontains $tenant) { - write-host "Unable to verify tenant or account" -f Red + Write-Host 'Unable to verify tenant or account' -f Red Disconnect-MgGraph - throw "Unable to continue due to validation" + throw 'Unable to continue due to validation' } # $authHeader = @{ @@ -106,19 +106,19 @@ NAME: Test-MgAuth # return $authHeader } catch { - write-host $_.Exception.Message -f Red - write-host $_.Exception.ItemName -f Red - write-host + Write-Host $_.Exception.Message -f Red + Write-Host $_.Exception.ItemName -f Red + Write-Host break } } - + #################################################### - + Function Create-GroupPolicyConfigurations() { - + <# .SYNOPSIS This function is used to add an device configuration policy using the Graph API REST interface @@ -130,49 +130,49 @@ Adds a device configuration policy in Intune .NOTES NAME: Add-DeviceConfigurationPolicy #> - - [cmdletbinding()] + + [CmdletBinding()] param ( $DisplayName ) - + $jsonCode = @" { "description":"", "displayName":"$($DisplayName)" } "@ - - $graphApiVersion = "Beta" - $DCP_resource = "deviceManagement/groupPolicyConfigurations" + + $graphApiVersion = 'Beta' + $DCP_resource = 'deviceManagement/groupPolicyConfigurations' Write-Verbose "Resource: $DCP_resource" - + try { - + $uri = "https://graph.microsoft.com/$graphApiVersion/$($DCP_resource)" - $responseBody = Invoke-MgGraphRequest -Uri $uri -Method Post -Body $jsonCode -ContentType "application/json" - - + $responseBody = Invoke-MgGraphRequest -Uri $uri -Method Post -Body $jsonCode -ContentType 'application/json' + + } - + catch { - + $ex = $_.Exception - + Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break - + } $responseBody.id } - - + + Function Create-GroupPolicyConfigurationsDefinitionValues() { - + <# .SYNOPSIS This function is used to get device configuration policies from the Graph API REST interface @@ -184,55 +184,55 @@ Function Create-GroupPolicyConfigurationsDefinitionValues() { .NOTES NAME: Get-GroupPolicyConfigurations #> - - [cmdletbinding()] + + [CmdletBinding()] Param ( - + [string]$GroupPolicyConfigurationID, $JSON - + ) - - $graphApiVersion = "Beta" - + + $graphApiVersion = 'Beta' + $DCP_resource = "deviceManagement/groupPolicyConfigurations/$($GroupPolicyConfigurationID)/definitionValues" - write-host $DCP_resource + Write-Host $DCP_resource try { - if ($JSON -eq "" -or $null -eq $JSON) { - - write-host "No JSON specified, please specify valid JSON for the Device Configuration Policy..." -f Red - + if ([string]::IsNullOrWhiteSpace($JSON)) { + + Write-Host 'No JSON specified, please specify valid JSON for the Device Configuration Policy...' -f Red + } - + else { - - Test-JSON -JSON $JSON - + + Test-Json -Json $JSON + $uri = "https://graph.microsoft.com/$graphApiVersion/$($DCP_resource)" - Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType "application/json" + Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType 'application/json' } - + } - + catch { - + $ex = $_.Exception - + Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break - + } - + } - - + + #################################################### Function Get-GroupPolicyConfigurations() { - + <# .SYNOPSIS This function is used to get device configuration policies from the Graph API REST interface @@ -244,37 +244,37 @@ Returns any device configuration policies configured in Intune .NOTES NAME: Get-GroupPolicyConfigurations #> - - [cmdletbinding()] + + [CmdletBinding()] param ( $name ) - - $graphApiVersion = "Beta" - $DCP_resource = "deviceManagement/groupPolicyConfigurations" - + + $graphApiVersion = 'Beta' + $DCP_resource = 'deviceManagement/groupPolicyConfigurations' + try { - + $uri = "https://graph.microsoft.com/$graphApiVersion/$($DCP_resource)" (Invoke-MgGraphRequest -Uri $uri -Method Get).Value | Where-Object { ($_.'displayName') -eq ("$Name") } - + } - + catch { - + $ex = $_.Exception - + Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break - + } - + } #################################################### @@ -293,7 +293,7 @@ Adds a device configuration policy assignment in Intune NAME: Add-DeviceConfigurationPolicyAssignment #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -302,27 +302,27 @@ NAME: Add-DeviceConfigurationPolicyAssignment $Assignment ) - $graphApiVersion = "Beta" + $graphApiVersion = 'Beta' $Resource = "deviceManagement/groupPolicyConfigurations/$ConfigurationPolicyId/assignments" - + try { if (!$ConfigurationPolicyId) { - write-host "No Configuration Policy Id specified, specify a valid Configuration Policy Id" -f Red + Write-Host 'No Configuration Policy Id specified, specify a valid Configuration Policy Id' -f Red break } if (!$TargetGroupId) { - write-host "No Target Group Id specified, specify a valid Target Group Id" -f Red + Write-Host 'No Target Group Id specified, specify a valid Target Group Id' -f Red break - + } if (!$Assignment) { - write-host "No Assignment Type specified, specify a valid Assignment Type" -f Red + Write-Host 'No Assignment Type specified, specify a valid Assignment Type' -f Red break } @@ -340,18 +340,18 @@ NAME: Add-DeviceConfigurationPolicyAssignment "@ $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)" - Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType "application/json" + Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType 'application/json' } - + catch { $ex = $_.Exception - + Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break } @@ -374,7 +374,7 @@ Returns all users registered with Azure AD NAME: Get-AADGroup #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -384,11 +384,11 @@ NAME: Get-AADGroup ) # Defining Variables - $graphApiVersion = "v1.0" - $Group_resource = "groups" + $graphApiVersion = 'v1.0' + $Group_resource = 'groups' # pseudo-group identifiers for all users and all devices - [string]$AllUsers = "acacacac-9df4-4c7d-9d50-4ef0226f57a9" - [string]$AllDevices = "adadadad-808e-44e2-905a-0b7873a8a531" + [string]$AllUsers = 'acacacac-9df4-4c7d-9d50-4ef0226f57a9' + [string]$AllDevices = 'adadadad-808e-44e2-905a-0b7873a8a531' try { @@ -396,14 +396,14 @@ NAME: Get-AADGroup $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)?`$filter=id eq '$id'" switch ( $id ) { - $AllUsers { $grp = [PSCustomObject]@{ displayName = "All users" }; $grp } - $AllDevices { $grp = [PSCustomObject]@{ displayName = "All devices" }; $grp } + $AllUsers { $grp = [PSCustomObject]@{ displayName = 'All users' }; $grp } + $AllDevices { $grp = [PSCustomObject]@{ displayName = 'All devices' }; $grp } default { (Invoke-MgGraphRequest -Uri $uri -Method Get).Value } } - + } - elseif ($GroupName -eq "" -or $null -eq $GroupName) { + elseif ([string]::IsNullOrWhiteSpace($GroupName)) { $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)" (Invoke-MgGraphRequest -Uri $uri -Method Get).Value @@ -429,7 +429,7 @@ NAME: Get-AADGroup $GID = $Group.id $Group.displayName - write-host + Write-Host $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)/$GID/Members" (Invoke-MgGraphRequest -Uri $uri -Method Get).Value @@ -445,11 +445,11 @@ NAME: Get-AADGroup catch { $ex = $_.Exception - + Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break } @@ -459,7 +459,7 @@ NAME: Get-AADGroup #################################################### Function Test-JSON() { - + <# .SYNOPSIS This function is used to test if the JSON passed to a REST Post request is valid @@ -471,57 +471,56 @@ Test if the JSON is valid before calling the Graph REST interface .NOTES NAME: Test-AuthHeader #> - + param ( - + $JSON - + ) - + try { - + $TestJSON = ConvertFrom-Json $JSON -ErrorAction Stop $validJson = $true - + } - + catch { - + $validJson = $false $_.Exception - + } - + if (!$validJson) { - + Write-Host "Provided JSON isn't in valid JSON format" -f Red break - + } - + } - + #################################################### - + #region Authentication - -write-host - + +Write-Host + # Defining User Principal Name if not present -if ($null -eq $User -or $User -eq "") { - - $User = Read-Host -Prompt "Please specify your user principal name for Azure Authentication" +if ([string]::IsNullOrWhiteSpace($User)) { + + $User = Read-Host -Prompt 'Please specify your user principal name for Azure Authentication' Write-Host } - + # Getting the authorization token Test-MgAuth -User $User - - + + #endregion - + #################################################### - # Replacing quotes for Test-Path $ImportPath = $ImportPath.replace('"', '') @@ -532,7 +531,7 @@ if (!(Test-Path "$ImportPath")) { Write-Host "Script can't continue..." -ForegroundColor Red Write-Host break - + } #################################################### @@ -540,7 +539,7 @@ if (!(Test-Path "$ImportPath")) { $TargetGroupId = (Get-AADGroup | Where-Object { $_.displayName -eq $AADGroup }).id -if ($null -eq $TargetGroupId -or $TargetGroupId -eq "") { +if ([string]::IsNullOrWhiteSpace($TargetGroupId)) { Write-Host "AAD Group - '$AADGroup' doesn't exist, please specify a valid AAD Group..." -ForegroundColor Red Write-Host @@ -552,42 +551,40 @@ if ($null -eq $TargetGroupId -or $TargetGroupId -eq "") { -Get-ChildItem $ImportPath -filter *.json | +Get-ChildItem $ImportPath -Filter *.json | ForEach-Object { $Policy_Name = $_.Name $Policy_Name = $Policy_Name.Substring(0, $Policy_Name.Length - 5) - + $DuplicateDCP = Get-GroupPolicyConfigurations -Name $Policy_Name - If ($DuplicateDCP -eq $null) - { + If ($DuplicateDCP -eq $null) { $GroupPolicyConfigurationID = Create-GroupPolicyConfigurations -DisplayName $Policy_Name $JSON_Data = Get-Content $_.FullName $JSON_Convert = $JSON_Data | ConvertFrom-Json $JSON_Convert | ForEach-Object { $_ - - $JSON_Output = Convertto-Json -Depth 5 $_ + + $JSON_Output = ConvertTo-Json -Depth 5 $_ Write-Host $JSON_Output - Create-GroupPolicyConfigurationsDefinitionValues -JSON $JSON_Output -GroupPolicyConfigurationID $GroupPolicyConfigurationID + Create-GroupPolicyConfigurationsDefinitionValues -JSON $JSON_Output -GroupPolicyConfigurationID $GroupPolicyConfigurationID } - Write-Host "####################################################################################################" -ForegroundColor Green - Write-Host "Policy: " $Policy_Name "created" -ForegroundColor Green - Write-Host "####################################################################################################" -ForegroundColor Green + Write-Host '####################################################################################################' -ForegroundColor Green + Write-Host 'Policy: ' $Policy_Name 'created' -ForegroundColor Green + Write-Host '####################################################################################################' -ForegroundColor Green $DeviceConfigs = Get-GroupPolicyConfigurations -name $Policy_Name $DeviceConfigID = $DeviceConfigs.id - - Add-GroupPolicyConfigurationPolicyAssignment -ConfigurationPolicyId $DeviceConfigID -TargetGroupId $TargetGroupId -Assignment "groupAssignmentTarget" + + Add-GroupPolicyConfigurationPolicyAssignment -ConfigurationPolicyId $DeviceConfigID -TargetGroupId $TargetGroupId -Assignment 'groupAssignmentTarget' } - else - { - write-host "Device Configuration ADMX Profile:" $Policy_Name "has already been created" -ForegroundColor Yellow + else { + Write-Host 'Device Configuration ADMX Profile:' $Policy_Name 'has already been created' -ForegroundColor Yellow } } diff --git a/ENT/MasterScript-ENT.ps1 b/ENT/MasterScript-ENT.ps1 index f07a92d..c4c2fa4 100644 --- a/ENT/MasterScript-ENT.ps1 +++ b/ENT/MasterScript-ENT.ps1 @@ -23,7 +23,7 @@ Authenticates you with the Graph API interface NAME: Test-MgAuth #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -45,7 +45,7 @@ NAME: Test-MgAuth write-host "Install by running 'Install-Module Microsoft.Graph' or 'Install-Module Microsoft.Graph' from an elevated PowerShell prompt" -f Yellow write-host "Script can't continue..." -f Red write-host - + } $scopes = @() @@ -53,19 +53,19 @@ NAME: Test-MgAuth ######################################### # Directory related scopes # ######################################### - $scopes += @("Device.Read.All", - "User.Read.All", - "GroupMember.ReadWrite.All", - "Group.ReadWrite.All", + $scopes += @("Device.Read.All", + "User.Read.All", + "GroupMember.ReadWrite.All", + "Group.ReadWrite.All", "Directory.ReadWrite.All") ######################################### # Device Management scopes # ######################################### - $scopes += @("DeviceManagementConfiguration.ReadWrite.All", - "DeviceManagementServiceConfig.ReadWrite.All", - "DeviceManagementRBAC.ReadWrite.All", - "DeviceManagementManagedDevices.ReadWrite.All", + $scopes += @("DeviceManagementConfiguration.ReadWrite.All", + "DeviceManagementServiceConfig.ReadWrite.All", + "DeviceManagementRBAC.ReadWrite.All", + "DeviceManagementManagedDevices.ReadWrite.All", "DeviceManagementApps.ReadWrite.All") @@ -105,17 +105,17 @@ NAME: Test-MgAuth } } - + #################################################### - + $User = Read-Host -Prompt "Please specify your user principal name for Microsoft Authentication" - + Test-MgAuth -user $user #################################################### - - + + write-host "Adding Device Configuration Profiles" . $ScriptDir/Import-ENT-DeviceConfiguration.ps1 diff --git a/ENT/Readme.md b/ENT/Readme.md index 8c27339..124c63a 100644 --- a/ENT/Readme.md +++ b/ENT/Readme.md @@ -1,7 +1,6 @@ - # Enterprise Profile configuration -The scripts for configuring the Enterprise security baseline are located in this folder. +The scripts for configuring the Enterprise security baseline are located in this folder. Before the scripts can be run install Azure AD powershell module on your device ```powershell @@ -13,24 +12,22 @@ Set-ExecutionPolicy remotesigned ``` [**MasterScript_ENT.PS1**](MasterScript-ENT.ps1) - This script is used to import the Compliance policies, Configuration profiles used to apply the Enterprise Profile settings - + To import the Enterprise Profile configuration settings into your tenant - Open powershell comsole - Navigate to ENT folder in Repo + Open powershell console + Navigate to ENT folder in Repo ```powershell .\MasterScript-ENT.ps1 ``` - + Enter **username** and **password** of an account that has Intune Administrator (preferred) or Global Admin privilege Wait for the import process to complete. The MasterScript_ENT.ps1 file calls the following scripts to import the Compliance Policies, Configuration Profiles - - [**Import-ENT-DeviceCompliancePolicies.ps1**](Import-ENT-DeviceCompliancePolicies.ps1) - This scripts imports the three device compliance policies for the Enterprise profile. Three policies are used to ensure that Conditional Access does not prevent a user from being able to access resources. Refer to [Windows 10 and later settings to mark devices as compliant or not compliant using Intune](https://docs.microsoft.com/en-us/mem/intune/protect/compliance-policy-create-windows) - + 1. [Enterprise Compliance ATP](JSON/DeviceCompliance/ENT-Compliance-ATP.json) policy is used to feed the Threat Intelligence data from Microsoft Defender for Endpoint into the devices compliance state so its signals can be used as part of the Conditional Access evaluation process. 2. [Enterprise Compliance Delayed](JSON/DeviceCompliance/ENT-Compliance-Delayed.json) policy applies a more complete set of compliance settings to the device but its application is delayed by 24 hours. this is because the device health attestation that is required to assess policies like BitLocker and Secure Boot is only calculated once a device has rebooted and then might take a number of hours to process whether the device is compliant or not. diff --git a/ENT/Scripts/ENT-DeviceConfig.ps1 b/ENT/Scripts/ENT-DeviceConfig.ps1 index 16a4bf7..fc4700d 100644 --- a/ENT/Scripts/ENT-DeviceConfig.ps1 +++ b/ENT/Scripts/ENT-DeviceConfig.ps1 @@ -19,17 +19,17 @@ Function Start-Log { [Parameter(HelpMessage = 'Deletes existing file if used with the -DeleteExistingFile switch')] [switch]$DeleteExistingFile ) - + Try { If (!(Test-Path $FilePath)) { ## Create the log file New-Item $FilePath -Type File -Force | Out-Null } - + If ($DeleteExistingFile) { Remove-Item $FilePath -Force } - + ## Set the global variable to be used as the FilePath for all subsequent Write-Log ## calls in this session $script:ScriptLogFilePath = $FilePath @@ -47,7 +47,7 @@ Function Start-Log { param ( [Parameter(Mandatory = $true)] [string]$Message, - + [Parameter()] [ValidateSet(1, 2, 3)] [int]$LogLevel = 1, @@ -81,7 +81,7 @@ NAME: Is-VM [CmdletBinding()] Param () - + Begin { Write-Log -Message "$($MyInvocation.InvocationName) function..." } @@ -96,7 +96,7 @@ NAME: Is-VM $True } else { - Write-Log -Message "Virtual string not found" + Write-Log -Message "Virtual string not found" $False } } @@ -123,7 +123,7 @@ NAME: Is-VM } Else { Write-Host "Machine is a physical device" - + #Enable Hibernate Write-Log -Message "Enabling Hibernation" $command = "C:\Windows\System32\PowerCfg.exe" @@ -170,7 +170,7 @@ NAME: Is-VM #Write-Warning "$($env:computername.ToUpper()) : $($_.Exception.message)" #Exit } - + $command = "C:\Windows\System32\PowerCfg.exe" $args = "/Change standby-timeout-ac 60" $workDir = "C:\Windows\System32" @@ -202,7 +202,7 @@ NAME: Is-VM } Catch { Write-Log -Message "Error changing registry: $($_.Exception.message)" - Write-Warning "Error: $($_.Exception.message)" + Write-Warning "Error: $($_.Exception.message)" Exit } Finally { @@ -220,27 +220,22 @@ NAME: Is-VM } Catch { Write-Log -Message "Error changing AppLocker DLL rule registry key: $($_.Exception.message)" - Write-Warning "Error: $($_.Exception.message)" + Write-Warning "Error: $($_.Exception.message)" Exit } Finally { Write-Log -Message "Finished changing AppLocker DLL rule registry key" } #endregion Configure AppLocker DLL rule registry key - + #region Configure additional Defender for Endpoint security recommendations that cannot be set in Configuration Profiles #Handle registry changes - - - Write-Log -Message "Configuring additional Defender for Endpoint security recommendations that cannot be set in Configuration Profiles" - # Require users to elevate when setting a network's location - prevent changing from Public to Private firewall profile - New-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Network Connections" -Name NC_StdDomainUserSetLocation -Value 1 -PropertyType DWORD -Force - Write-Log -Message "Require users to elevate when setting a network's location - prevent changing from Public to Private firewall profile registry update successfully applied" - # Prevent saving of network credentials + + # Prevent saving of network credentials New-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Control\Lsa -Name DisableDomainCreds -Value 1 -PropertyType DWORD -Force Write-Log -Message "Prevent saving of network credentials registry update successfully applied" # Prevent changing proxy config - + #region Disable Network Location Wizard - prevents users from setting network location as Private and therefore increasing the attack surface exposed in Windows Firewall #region Disable Network Location Wizard #Handle registry changes @@ -260,7 +255,7 @@ NAME: Is-VM } Catch { Write-Log -Message "Error changing registry: $($_.Exception.message)" - Write-Warning "Error: $($_.Exception.message)" + Write-Warning "Error: $($_.Exception.message)" Exit } Finally { @@ -310,7 +305,7 @@ NAME: Is-VM } #endregion Remove WindowsMediaPlayer - + #region RegistryChanges - Set W32Time Parameter Type to NTP #Handle registry changes $registryPath = "HKLM:\SYSTEM\CurrentControlSet\Services\W32Time\Parameters" @@ -332,7 +327,7 @@ NAME: Is-VM } Catch { Write-Log -Message "Error changing registry: $($_.Exception.message)" - Write-Warning "Error: $($_.Exception.message)" + Write-Warning "Error: $($_.Exception.message)" Exit } Finally { @@ -361,14 +356,14 @@ NAME: Is-VM } Catch { Write-Log -Message "Error changing registry: $($_.Exception.message)" - Write-Warning "Error: $($_.Exception.message)" + Write-Warning "Error: $($_.Exception.message)" Exit } Finally { Write-Log -Message "Set Auto Time Sync Service to Automatic start" } #endregion RegistryChanges - Set Auto Time Sync Service to Automatic start - + #region Remove Internet Explorer 11 <#try { diff --git a/Legacy/DeviceCompliance_NCSC-Windows10(1803).ps1 b/Legacy/DeviceCompliance_NCSC-Windows10(1803).ps1 index 094911c..388d6dc 100644 --- a/Legacy/DeviceCompliance_NCSC-Windows10(1803).ps1 +++ b/Legacy/DeviceCompliance_NCSC-Windows10(1803).ps1 @@ -1,19 +1,19 @@ <################################################################################################## # .SYNOPSIS -This is a script steps up the NSCS workstation compliance settings For DeviceConfiguration_NCSC -Baseline: https://www.ncsc.gov.uk/guidance/eud-guidance-windows-10-1803-mobile-device-management +This is a script steps up the NSCS workstation compliance settings For DeviceConfiguration_NCSC +Baseline: https://www.ncsc.gov.uk/guidance/eud-guidance-windows-10-1803-mobile-device-management .NOTES FileName: DeviceCompliance_NCSC - Windows10 (1803).ps1 - Author: Per Larsen + Author: Per Larsen Revised: Frank Simorjay Created: 03-09-2018 Revised: 05-09-2019 - Version: 1.0 - + Version: 1.0 + #> ################################################################################################### <# @@ -28,7 +28,7 @@ See LICENSE in the project root for license information. function Get-AuthToken { -<# + <# .SYNOPSIS This function is used to authenticate with the Graph API REST interface .DESCRIPTION @@ -40,114 +40,114 @@ Authenticates you with the Graph API interface NAME: Get-AuthToken #> -[cmdletbinding()] + [CmdletBinding()] -param -( - [Parameter(Mandatory=$true)] - $User -) + param + ( + [Parameter(Mandatory = $true)] + $User + ) -$userUpn = New-Object "System.Net.Mail.MailAddress" -ArgumentList $User + $userUpn = New-Object 'System.Net.Mail.MailAddress' -ArgumentList $User -$tenant = $userUpn.Host + $tenant = $userUpn.Host -Write-Host "Checking for AzureAD module..." + Write-Host 'Checking for AzureAD module...' - $AadModule = Get-Module -Name "AzureAD" -ListAvailable + $AadModule = Get-Module -Name 'AzureAD' -ListAvailable if ($AadModule -eq $null) { - Write-Host "AzureAD PowerShell module not found, looking for AzureADPreview" - $AadModule = Get-Module -Name "AzureADPreview" -ListAvailable + Write-Host 'AzureAD PowerShell module not found, looking for AzureADPreview' + $AadModule = Get-Module -Name 'AzureADPreview' -ListAvailable } if ($AadModule -eq $null) { - write-host - write-host "AzureAD Powershell module not installed..." -f Red - write-host "Install by running 'Install-Module AzureAD' or 'Install-Module AzureADPreview' from an elevated PowerShell prompt" -f Yellow - write-host "Script can't continue..." -f Red - write-host + Write-Host + Write-Host 'AzureAD Powershell module not installed...' -f Red + Write-Host "Install by running 'Install-Module AzureAD' or 'Install-Module AzureADPreview' from an elevated PowerShell prompt" -f Yellow + Write-Host "Script can't continue..." -f Red + Write-Host exit } -# Getting path to ActiveDirectory Assemblies -# If the module count is greater than 1 find the latest version + # Getting path to ActiveDirectory Assemblies + # If the module count is greater than 1 find the latest version - if($AadModule.count -gt 1){ + if ($AadModule.count -gt 1) { - $Latest_Version = ($AadModule | select version | Sort-Object)[-1] + $Latest_Version = ($AadModule | Select-Object version | Sort-Object)[-1] - $aadModule = $AadModule | ? { $_.version -eq $Latest_Version.version } + $aadModule = $AadModule | Where-Object { $_.version -eq $Latest_Version.version } - # Checking if there are multiple versions of the same module found + # Checking if there are multiple versions of the same module found - if($AadModule.count -gt 1){ + if ($AadModule.count -gt 1) { - $aadModule = $AadModule | select -Unique + $aadModule = $AadModule | Select-Object -Unique - } + } - $adal = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.dll" - $adalforms = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll" + $adal = Join-Path $AadModule.ModuleBase 'Microsoft.IdentityModel.Clients.ActiveDirectory.dll' + $adalforms = Join-Path $AadModule.ModuleBase 'Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll' } else { - $adal = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.dll" - $adalforms = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll" + $adal = Join-Path $AadModule.ModuleBase 'Microsoft.IdentityModel.Clients.ActiveDirectory.dll' + $adalforms = Join-Path $AadModule.ModuleBase 'Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll' } -[System.Reflection.Assembly]::LoadFrom($adal) | Out-Null + [System.Reflection.Assembly]::LoadFrom($adal) | Out-Null -[System.Reflection.Assembly]::LoadFrom($adalforms) | Out-Null + [System.Reflection.Assembly]::LoadFrom($adalforms) | Out-Null -$clientId = "d1ddf0e4-d672-4dae-b554-9d5bdfd93547" + $clientId = 'd1ddf0e4-d672-4dae-b554-9d5bdfd93547' -$redirectUri = "urn:ietf:wg:oauth:2.0:oob" + $redirectUri = 'urn:ietf:wg:oauth:2.0:oob' -$resourceAppIdURI = "https://graph.microsoft.com" + $resourceAppIdURI = 'https://graph.microsoft.com' -$authority = "https://login.microsoftonline.com/$Tenant" + $authority = "https://login.microsoftonline.com/$Tenant" try { - $authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority + $authContext = New-Object 'Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext' -ArgumentList $authority - # https://msdn.microsoft.com/en-us/library/azure/microsoft.identitymodel.clients.activedirectory.promptbehavior.aspx - # Change the prompt behaviour to force credentials each time: Auto, Always, Never, RefreshSession + # https://msdn.microsoft.com/en-us/library/azure/microsoft.identitymodel.clients.activedirectory.promptbehavior.aspx + # Change the prompt behaviour to force credentials each time: Auto, Always, Never, RefreshSession - $platformParameters = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.PlatformParameters" -ArgumentList "Auto" + $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.UserIdentifier' -ArgumentList ($User, 'OptionalDisplayableId') - $authResult = $authContext.AcquireTokenAsync($resourceAppIdURI,$clientId,$redirectUri,$platformParameters,$userId).Result + $authResult = $authContext.AcquireTokenAsync($resourceAppIdURI, $clientId, $redirectUri, $platformParameters, $userId).Result # If the accesstoken is valid then create the authentication header - if($authResult.AccessToken){ + if ($authResult.AccessToken) { - # Creating header for Authorization token + # Creating header for Authorization token - $authHeader = @{ - 'Content-Type'='application/json' - 'Authorization'="Bearer " + $authResult.AccessToken - 'ExpiresOn'=$authResult.ExpiresOn + $authHeader = @{ + 'Content-Type' = 'application/json' + 'Authorization' = 'Bearer ' + $authResult.AccessToken + 'ExpiresOn' = $authResult.ExpiresOn } - return $authHeader + return $authHeader } else { - Write-Host - Write-Host "Authorization Access Token is null, please re-run authentication..." -ForegroundColor Red - Write-Host - break + Write-Host + Write-Host 'Authorization Access Token is null, please re-run authentication...' -ForegroundColor Red + Write-Host + break } @@ -155,10 +155,10 @@ $authority = "https://login.microsoftonline.com/$Tenant" catch { - write-host $_.Exception.Message -f Red - write-host $_.Exception.ItemName -f Red - write-host - break + Write-Host $_.Exception.Message -f Red + Write-Host $_.Exception.ItemName -f Red + Write-Host + break } @@ -166,9 +166,9 @@ $authority = "https://login.microsoftonline.com/$Tenant" #################################################### -Function Add-DeviceConfigurationPolicy(){ +Function Add-DeviceConfigurationPolicy() { -<# + <# .SYNOPSIS This function is used to add an device configuration policy using the Graph API REST interface .DESCRIPTION @@ -180,31 +180,31 @@ Adds a device configuration policy in Intune NAME: Add-DeviceConfigurationPolicy #> -[cmdletbinding()] + [CmdletBinding()] -param -( - $JSON -) + param + ( + $JSON + ) -$graphApiVersion = "Beta" -$DCP_resource = "deviceManagement/deviceConfigurations" -Write-Verbose "Resource: $DCP_resource" + $graphApiVersion = 'Beta' + $DCP_resource = 'deviceManagement/deviceConfigurations' + Write-Verbose "Resource: $DCP_resource" try { - if($JSON -eq "" -or $JSON -eq $null){ + if ([string]::IsNullOrWhiteSpace($JSON)) { - write-host "No JSON specified, please specify valid JSON for the Android Policy..." -f Red + Write-Host 'No JSON specified, please specify valid JSON for the Android Policy...' -f Red } else { - Test-JSON -JSON $JSON + Test-Json -Json $JSON - $uri = "https://graph.microsoft.com/$graphApiVersion/$($DCP_resource)" - Invoke-RestMethod -Uri $uri -Headers $authToken -Method Post -Body $JSON -ContentType "application/json" + $uri = "https://graph.microsoft.com/$graphApiVersion/$($DCP_resource)" + Invoke-RestMethod -Uri $uri -Headers $authToken -Method Post -Body $JSON -ContentType 'application/json' } @@ -212,16 +212,16 @@ Write-Verbose "Resource: $DCP_resource" 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 + $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 } @@ -229,9 +229,9 @@ Write-Verbose "Resource: $DCP_resource" #################################################### -Function Test-JSON(){ +Function Test-JSON() { -<# + <# .SYNOPSIS This function is used to test if the JSON passed to a REST Post request is valid .DESCRIPTION @@ -243,30 +243,30 @@ Test if the JSON is valid before calling the Graph REST interface NAME: Test-AuthHeader #> -param ( + param ( -$JSON + $JSON -) + ) try { - $TestJSON = ConvertFrom-Json $JSON -ErrorAction Stop - $validJson = $true + $TestJSON = ConvertFrom-Json $JSON -ErrorAction Stop + $validJson = $true } catch { - $validJson = $false - $_.Exception + $validJson = $false + $_.Exception } - if (!$validJson){ + if (!$validJson) { - Write-Host "Provided JSON isn't in valid JSON format" -f Red - break + Write-Host "Provided JSON isn't in valid JSON format" -f Red + break } @@ -275,7 +275,7 @@ $JSON #################################################### -Function Add-DeviceCompliancePolicybaseline(){ +Function Add-DeviceCompliancePolicybaseline() { <# .SYNOPSIS @@ -288,62 +288,62 @@ Function Add-DeviceCompliancePolicybaseline(){ .NOTES NAME: Add-DeviceCompliancePolicy #> - - [cmdletbinding()] - + + [CmdletBinding()] + param ( $JSON ) - - $graphApiVersion = "Beta" - $Resource = "deviceManagement/deviceCompliancePolicies" - - try { - - if($JSON -eq "" -or $JSON -eq $null){ - - write-host "No JSON specified, please specify valid JSON for the iOS Policy..." -f Red - - } - - else { - - Test-JSON -JSON $JSON - + + $graphApiVersion = 'Beta' + $Resource = 'deviceManagement/deviceCompliancePolicies' + + try { + + if ([string]::IsNullOrWhiteSpace($JSON)) { + + Write-Host 'No JSON specified, please specify valid JSON for the iOS Policy...' -f Red + + } + + else { + + Test-Json -Json $JSON + $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)" - Invoke-RestMethod -Uri $uri -Headers $authToken -Method Post -Body $JSON -ContentType "application/json" - - } - + Invoke-RestMethod -Uri $uri -Headers $authToken -Method Post -Body $JSON -ContentType 'application/json' + } - - catch { - + + } + + catch { + $ex = $_.Exception $errorResponse = $ex.Response.GetResponseStream() $reader = New-Object System.IO.StreamReader($errorResponse) $reader.BaseStream.Position = 0 $reader.DiscardBufferedData() - $responseBody = $reader.ReadToEnd(); + $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 + Write-Host break - - } - + } - - #################################################### + +} + +#################################################### #################################################### #region Authentication -write-host +Write-Host # Checking if authToken exists before running authentication -if($global:authToken){ +if ($global:authToken) { # Setting DateTime to Universal time to work in all timezones $DateTime = (Get-Date).ToUniversalTime() @@ -351,36 +351,36 @@ if($global:authToken){ # If the authToken exists checking when it expires $TokenExpires = ($authToken.ExpiresOn.datetime - $DateTime).Minutes - if($TokenExpires -le 0){ + if ($TokenExpires -le 0) { - write-host "Authentication Token expired" $TokenExpires "minutes ago" -ForegroundColor Yellow - write-host + Write-Host 'Authentication Token expired' $TokenExpires 'minutes ago' -ForegroundColor Yellow + Write-Host - # Defining User Principal Name if not present + # Defining User Principal Name if not present - if($User -eq $null -or $User -eq ""){ - $User = Read-Host -Prompt "Please specify your user principal name for Azure Authentication" + if ([string]::IsNullOrWhiteSpace($User)) { + $User = Read-Host -Prompt 'Please specify your user principal name for Azure Authentication' Write-Host - } + } $global:authToken = Get-AuthToken -User $User - } + } } # Authentication doesn't exist, calling Get-AuthToken function else { - if($User -eq $null -or $User -eq ""){ - $User = Read-Host -Prompt "Please specify your user principal name for Azure Authentication" - Write-Host + if ([string]::IsNullOrWhiteSpace($User)) { + $User = Read-Host -Prompt 'Please specify your user principal name for Azure Authentication' + Write-Host } -# Getting the authorization token -$global:authToken = Get-AuthToken -User $User + # Getting the authorization token + $global:authToken = Get-AuthToken -User $User } @@ -393,7 +393,7 @@ $global:authToken = Get-AuthToken -User $User #################################################### -$Baseline = @" +$Baseline = @' { "@odata.type": "#microsoft.graph.windows10CompliancePolicy", @@ -435,7 +435,7 @@ $Baseline = @" } -"@ +'@ #################################################### diff --git a/Legacy/Enhanced-Workstation-Windows10-(1809).ps1 b/Legacy/Enhanced-Workstation-Windows10-(1809).ps1 index 1034414..4c25e18 100644 --- a/Legacy/Enhanced-Workstation-Windows10-(1809).ps1 +++ b/Legacy/Enhanced-Workstation-Windows10-(1809).ps1 @@ -1,18 +1,18 @@ <################################################################################################## # .SYNOPSIS -This is a script imports the Enhanced security baseline and configurations as a starting point for -By design the sripts enable hardening and logging, and is designed to be a step towards the secured workstation. +This is a script imports the Enhanced security baseline and configurations as a starting point for +By design the scripts enable hardening and logging, and is designed to be a step towards the secured workstation. .NOTES FileName: Enhanced Workstation - Windows10 (1809) SecurityBaseline.ps1 - Author: Per Larsen + Author: Per Larsen Revised: Frank Simorjay Created: 03-09-2018 Revised: 05-09-2019 - Version: 1.1 hardended - + Version: 1.1 hardened + #> ################################################################################################### <# @@ -27,7 +27,7 @@ See LICENSE in the project root for license information. function Get-AuthToken { -<# + <# .SYNOPSIS This function is used to authenticate with the Graph API REST interface .DESCRIPTION @@ -39,114 +39,114 @@ Authenticates you with the Graph API interface NAME: Get-AuthToken #> -[cmdletbinding()] + [CmdletBinding()] -param -( - [Parameter(Mandatory=$true)] - $User -) + param + ( + [Parameter(Mandatory = $true)] + $User + ) -$userUpn = New-Object "System.Net.Mail.MailAddress" -ArgumentList $User + $userUpn = New-Object 'System.Net.Mail.MailAddress' -ArgumentList $User -$tenant = $userUpn.Host + $tenant = $userUpn.Host -Write-Host "Checking for AzureAD module..." + Write-Host 'Checking for AzureAD module...' - $AadModule = Get-Module -Name "AzureAD" -ListAvailable + $AadModule = Get-Module -Name 'AzureAD' -ListAvailable if ($AadModule -eq $null) { - Write-Host "AzureAD PowerShell module not found, looking for AzureADPreview" - $AadModule = Get-Module -Name "AzureADPreview" -ListAvailable + Write-Host 'AzureAD PowerShell module not found, looking for AzureADPreview' + $AadModule = Get-Module -Name 'AzureADPreview' -ListAvailable } if ($AadModule -eq $null) { - write-host - write-host "AzureAD Powershell module not installed..." -f Red - write-host "Install by running 'Install-Module AzureAD' or 'Install-Module AzureADPreview' from an elevated PowerShell prompt" -f Yellow - write-host "Script can't continue..." -f Red - write-host + Write-Host + Write-Host 'AzureAD Powershell module not installed...' -f Red + Write-Host "Install by running 'Install-Module AzureAD' or 'Install-Module AzureADPreview' from an elevated PowerShell prompt" -f Yellow + Write-Host "Script can't continue..." -f Red + Write-Host exit } -# Getting path to ActiveDirectory Assemblies -# If the module count is greater than 1 find the latest version + # Getting path to ActiveDirectory Assemblies + # If the module count is greater than 1 find the latest version - if($AadModule.count -gt 1){ + if ($AadModule.count -gt 1) { - $Latest_Version = ($AadModule | select version | Sort-Object)[-1] + $Latest_Version = ($AadModule | Select-Object version | Sort-Object)[-1] - $aadModule = $AadModule | ? { $_.version -eq $Latest_Version.version } + $aadModule = $AadModule | Where-Object { $_.version -eq $Latest_Version.version } - # Checking if there are multiple versions of the same module found + # Checking if there are multiple versions of the same module found - if($AadModule.count -gt 1){ + if ($AadModule.count -gt 1) { - $aadModule = $AadModule | select -Unique + $aadModule = $AadModule | Select-Object -Unique - } + } - $adal = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.dll" - $adalforms = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll" + $adal = Join-Path $AadModule.ModuleBase 'Microsoft.IdentityModel.Clients.ActiveDirectory.dll' + $adalforms = Join-Path $AadModule.ModuleBase 'Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll' } else { - $adal = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.dll" - $adalforms = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll" + $adal = Join-Path $AadModule.ModuleBase 'Microsoft.IdentityModel.Clients.ActiveDirectory.dll' + $adalforms = Join-Path $AadModule.ModuleBase 'Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll' } -[System.Reflection.Assembly]::LoadFrom($adal) | Out-Null + [System.Reflection.Assembly]::LoadFrom($adal) | Out-Null -[System.Reflection.Assembly]::LoadFrom($adalforms) | Out-Null + [System.Reflection.Assembly]::LoadFrom($adalforms) | Out-Null -$clientId = "d1ddf0e4-d672-4dae-b554-9d5bdfd93547" + $clientId = 'd1ddf0e4-d672-4dae-b554-9d5bdfd93547' -$redirectUri = "urn:ietf:wg:oauth:2.0:oob" + $redirectUri = 'urn:ietf:wg:oauth:2.0:oob' -$resourceAppIdURI = "https://graph.microsoft.com" + $resourceAppIdURI = 'https://graph.microsoft.com' -$authority = "https://login.microsoftonline.com/$Tenant" + $authority = "https://login.microsoftonline.com/$Tenant" try { - $authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority + $authContext = New-Object 'Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext' -ArgumentList $authority - # https://msdn.microsoft.com/en-us/library/azure/microsoft.identitymodel.clients.activedirectory.promptbehavior.aspx - # Change the prompt behaviour to force credentials each time: Auto, Always, Never, RefreshSession + # https://msdn.microsoft.com/en-us/library/azure/microsoft.identitymodel.clients.activedirectory.promptbehavior.aspx + # Change the prompt behaviour to force credentials each time: Auto, Always, Never, RefreshSession - $platformParameters = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.PlatformParameters" -ArgumentList "Auto" + $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.UserIdentifier' -ArgumentList ($User, 'OptionalDisplayableId') - $authResult = $authContext.AcquireTokenAsync($resourceAppIdURI,$clientId,$redirectUri,$platformParameters,$userId).Result + $authResult = $authContext.AcquireTokenAsync($resourceAppIdURI, $clientId, $redirectUri, $platformParameters, $userId).Result # If the accesstoken is valid then create the authentication header - if($authResult.AccessToken){ + if ($authResult.AccessToken) { - # Creating header for Authorization token + # Creating header for Authorization token - $authHeader = @{ - 'Content-Type'='application/json' - 'Authorization'="Bearer " + $authResult.AccessToken - 'ExpiresOn'=$authResult.ExpiresOn + $authHeader = @{ + 'Content-Type' = 'application/json' + 'Authorization' = 'Bearer ' + $authResult.AccessToken + 'ExpiresOn' = $authResult.ExpiresOn } - return $authHeader + return $authHeader } else { - Write-Host - Write-Host "Authorization Access Token is null, please re-run authentication..." -ForegroundColor Red - Write-Host - break + Write-Host + Write-Host 'Authorization Access Token is null, please re-run authentication...' -ForegroundColor Red + Write-Host + break } @@ -154,10 +154,10 @@ $authority = "https://login.microsoftonline.com/$Tenant" catch { - write-host $_.Exception.Message -f Red - write-host $_.Exception.ItemName -f Red - write-host - break + Write-Host $_.Exception.Message -f Red + Write-Host $_.Exception.ItemName -f Red + Write-Host + break } @@ -165,9 +165,9 @@ $authority = "https://login.microsoftonline.com/$Tenant" #################################################### -Function Add-DeviceConfigurationPolicy(){ +Function Add-DeviceConfigurationPolicy() { -<# + <# .SYNOPSIS This function is used to add an device configuration policy using the Graph API REST interface .DESCRIPTION @@ -179,31 +179,31 @@ Adds a device configuration policy in Intune NAME: Add-DeviceConfigurationPolicy #> -[cmdletbinding()] + [CmdletBinding()] -param -( - $JSON -) + param + ( + $JSON + ) -$graphApiVersion = "Beta" -$DCP_resource = "deviceManagement/deviceConfigurations" -Write-Verbose "Resource: $DCP_resource" + $graphApiVersion = 'Beta' + $DCP_resource = 'deviceManagement/deviceConfigurations' + Write-Verbose "Resource: $DCP_resource" try { - if($JSON -eq "" -or $JSON -eq $null){ + if ([string]::IsNullOrWhiteSpace($JSON)) { - write-host "No JSON specified, please specify valid JSON for the Android Policy..." -f Red + Write-Host 'No JSON specified, please specify valid JSON for the Android Policy...' -f Red } else { - Test-JSON -JSON $JSON + Test-Json -Json $JSON - $uri = "https://graph.microsoft.com/$graphApiVersion/$($DCP_resource)" - Invoke-RestMethod -Uri $uri -Headers $authToken -Method Post -Body $JSON -ContentType "application/json" + $uri = "https://graph.microsoft.com/$graphApiVersion/$($DCP_resource)" + Invoke-RestMethod -Uri $uri -Headers $authToken -Method Post -Body $JSON -ContentType 'application/json' } @@ -211,16 +211,16 @@ Write-Verbose "Resource: $DCP_resource" 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 + $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 } @@ -228,9 +228,9 @@ Write-Verbose "Resource: $DCP_resource" #################################################### -Function Test-JSON(){ +Function Test-JSON() { -<# + <# .SYNOPSIS This function is used to test if the JSON passed to a REST Post request is valid .DESCRIPTION @@ -242,30 +242,30 @@ Test if the JSON is valid before calling the Graph REST interface NAME: Test-AuthHeader #> -param ( + param ( -$JSON + $JSON -) + ) try { - $TestJSON = ConvertFrom-Json $JSON -ErrorAction Stop - $validJson = $true + $TestJSON = ConvertFrom-Json $JSON -ErrorAction Stop + $validJson = $true } catch { - $validJson = $false - $_.Exception + $validJson = $false + $_.Exception } - if (!$validJson){ + if (!$validJson) { - Write-Host "Provided JSON isn't in valid JSON format" -f Red - break + Write-Host "Provided JSON isn't in valid JSON format" -f Red + break } @@ -274,7 +274,7 @@ $JSON #################################################### -Function Add-DeviceCompliancePolicybaseline(){ +Function Add-DeviceCompliancePolicybaseline() { <# .SYNOPSIS @@ -287,62 +287,62 @@ Function Add-DeviceCompliancePolicybaseline(){ .NOTES NAME: Add-DeviceCompliancePolicy #> - - [cmdletbinding()] - + + [CmdletBinding()] + param ( $JSON ) - - $graphApiVersion = "Beta" - $Resource = "deviceManagement/deviceCompliancePolicies" - - try { - - if($JSON -eq "" -or $JSON -eq $null){ - - write-host "No JSON specified, please specify valid JSON for the iOS Policy..." -f Red - - } - - else { - - Test-JSON -JSON $JSON - + + $graphApiVersion = 'Beta' + $Resource = 'deviceManagement/deviceCompliancePolicies' + + try { + + if ([string]::IsNullOrWhiteSpace($JSON)) { + + Write-Host 'No JSON specified, please specify valid JSON for the iOS Policy...' -f Red + + } + + else { + + Test-Json -Json $JSON + $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)" - Invoke-RestMethod -Uri $uri -Headers $authToken -Method Post -Body $JSON -ContentType "application/json" - - } - + Invoke-RestMethod -Uri $uri -Headers $authToken -Method Post -Body $JSON -ContentType 'application/json' + } - - catch { - + + } + + catch { + $ex = $_.Exception $errorResponse = $ex.Response.GetResponseStream() $reader = New-Object System.IO.StreamReader($errorResponse) $reader.BaseStream.Position = 0 $reader.DiscardBufferedData() - $responseBody = $reader.ReadToEnd(); + $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 + Write-Host break - - } - + } - - #################################################### + +} + +#################################################### #################################################### #region Authentication -write-host +Write-Host # Checking if authToken exists before running authentication -if($global:authToken){ +if ($global:authToken) { # Setting DateTime to Universal time to work in all timezones $DateTime = (Get-Date).ToUniversalTime() @@ -350,36 +350,36 @@ if($global:authToken){ # If the authToken exists checking when it expires $TokenExpires = ($authToken.ExpiresOn.datetime - $DateTime).Minutes - if($TokenExpires -le 0){ + if ($TokenExpires -le 0) { - write-host "Authentication Token expired" $TokenExpires "minutes ago" -ForegroundColor Yellow - write-host + Write-Host 'Authentication Token expired' $TokenExpires 'minutes ago' -ForegroundColor Yellow + Write-Host - # Defining User Principal Name if not present + # Defining User Principal Name if not present - if($User -eq $null -or $User -eq ""){ - $User = Read-Host -Prompt "Please specify your user principal name for Azure Authentication" + if ([string]::IsNullOrWhiteSpace($User)) { + $User = Read-Host -Prompt 'Please specify your user principal name for Azure Authentication' Write-Host - } + } $global:authToken = Get-AuthToken -User $User - } + } } # Authentication doesn't exist, calling Get-AuthToken function else { - if($User -eq $null -or $User -eq ""){ - $User = Read-Host -Prompt "Please specify your user principal name for Azure Authentication" - Write-Host + if ([string]::IsNullOrWhiteSpace($User)) { + $User = Read-Host -Prompt 'Please specify your user principal name for Azure Authentication' + Write-Host } -# Getting the authorization token -$global:authToken = Get-AuthToken -User $User + # Getting the authorization token + $global:authToken = Get-AuthToken -User $User } @@ -394,7 +394,7 @@ $global:authToken = Get-AuthToken -User $User #################################################### -$firewall = @" +$firewall = @' { @@ -703,12 +703,12 @@ $firewall = @" "blockCrossOrganizationWriteAccess": false } } -"@ +'@ #################################################### -$System1 = @" +$System1 = @' { "@odata.type": "#microsoft.graph.windows10GeneralConfiguration", @@ -1012,12 +1012,12 @@ $System1 = @" "severeSeverity": "quarantine" } } -"@ +'@ #################################################### #################################################### -$Baseline = @" +$Baseline = @' { "@odata.type": "#microsoft.graph.windows10CompliancePolicy", @@ -1059,7 +1059,7 @@ $Baseline = @" } -"@ +'@ #################################################### Add-DeviceConfigurationPolicy -Json $Firewall # OK diff --git a/Legacy/HighSecurityWorkstation-Windows10-(1809).ps1 b/Legacy/HighSecurityWorkstation-Windows10-(1809).ps1 index 4d6d77f..48faad8 100644 --- a/Legacy/HighSecurityWorkstation-Windows10-(1809).ps1 +++ b/Legacy/HighSecurityWorkstation-Windows10-(1809).ps1 @@ -1,18 +1,18 @@ <################################################################################################## # .SYNOPSIS -This is a script imports the High security baseline and configurations as a starting point for -By design the sripts enable hardening and logging, and is designed to be a step towards the secured workstation. +This is a script imports the High security baseline and configurations as a starting point for +By design the scripts enable hardening and logging, and is designed to be a step towards the secured workstation. .NOTES FileName: HighSecurity Workstation - Windows10 (1809) SecurityBaseline.ps1 - Author: Per Larsen + Author: Per Larsen Revised: Frank Simorjay Created: 03-09-2018 Revised: 05-09-2019 - Version: 1.1 hardended - + Version: 1.1 hardened + #> ################################################################################################### <# @@ -27,7 +27,7 @@ See LICENSE in the project root for license information. function Get-AuthToken { -<# + <# .SYNOPSIS This function is used to authenticate with the Graph API REST interface .DESCRIPTION @@ -39,114 +39,114 @@ Authenticates you with the Graph API interface NAME: Get-AuthToken #> -[cmdletbinding()] + [CmdletBinding()] -param -( - [Parameter(Mandatory=$true)] - $User -) + param + ( + [Parameter(Mandatory = $true)] + $User + ) -$userUpn = New-Object "System.Net.Mail.MailAddress" -ArgumentList $User + $userUpn = New-Object 'System.Net.Mail.MailAddress' -ArgumentList $User -$tenant = $userUpn.Host + $tenant = $userUpn.Host -Write-Host "Checking for AzureAD module..." + Write-Host 'Checking for AzureAD module...' - $AadModule = Get-Module -Name "AzureAD" -ListAvailable + $AadModule = Get-Module -Name 'AzureAD' -ListAvailable if ($AadModule -eq $null) { - Write-Host "AzureAD PowerShell module not found, looking for AzureADPreview" - $AadModule = Get-Module -Name "AzureADPreview" -ListAvailable + Write-Host 'AzureAD PowerShell module not found, looking for AzureADPreview' + $AadModule = Get-Module -Name 'AzureADPreview' -ListAvailable } if ($AadModule -eq $null) { - write-host - write-host "AzureAD Powershell module not installed..." -f Red - write-host "Install by running 'Install-Module AzureAD' or 'Install-Module AzureADPreview' from an elevated PowerShell prompt" -f Yellow - write-host "Script can't continue..." -f Red - write-host + Write-Host + Write-Host 'AzureAD Powershell module not installed...' -f Red + Write-Host "Install by running 'Install-Module AzureAD' or 'Install-Module AzureADPreview' from an elevated PowerShell prompt" -f Yellow + Write-Host "Script can't continue..." -f Red + Write-Host exit } -# Getting path to ActiveDirectory Assemblies -# If the module count is greater than 1 find the latest version + # Getting path to ActiveDirectory Assemblies + # If the module count is greater than 1 find the latest version - if($AadModule.count -gt 1){ + if ($AadModule.count -gt 1) { - $Latest_Version = ($AadModule | select version | Sort-Object)[-1] + $Latest_Version = ($AadModule | Select-Object version | Sort-Object)[-1] - $aadModule = $AadModule | ? { $_.version -eq $Latest_Version.version } + $aadModule = $AadModule | Where-Object { $_.version -eq $Latest_Version.version } - # Checking if there are multiple versions of the same module found + # Checking if there are multiple versions of the same module found - if($AadModule.count -gt 1){ + if ($AadModule.count -gt 1) { - $aadModule = $AadModule | select -Unique + $aadModule = $AadModule | Select-Object -Unique - } + } - $adal = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.dll" - $adalforms = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll" + $adal = Join-Path $AadModule.ModuleBase 'Microsoft.IdentityModel.Clients.ActiveDirectory.dll' + $adalforms = Join-Path $AadModule.ModuleBase 'Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll' } else { - $adal = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.dll" - $adalforms = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll" + $adal = Join-Path $AadModule.ModuleBase 'Microsoft.IdentityModel.Clients.ActiveDirectory.dll' + $adalforms = Join-Path $AadModule.ModuleBase 'Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll' } -[System.Reflection.Assembly]::LoadFrom($adal) | Out-Null + [System.Reflection.Assembly]::LoadFrom($adal) | Out-Null -[System.Reflection.Assembly]::LoadFrom($adalforms) | Out-Null + [System.Reflection.Assembly]::LoadFrom($adalforms) | Out-Null -$clientId = "d1ddf0e4-d672-4dae-b554-9d5bdfd93547" + $clientId = 'd1ddf0e4-d672-4dae-b554-9d5bdfd93547' -$redirectUri = "urn:ietf:wg:oauth:2.0:oob" + $redirectUri = 'urn:ietf:wg:oauth:2.0:oob' -$resourceAppIdURI = "https://graph.microsoft.com" + $resourceAppIdURI = 'https://graph.microsoft.com' -$authority = "https://login.microsoftonline.com/$Tenant" + $authority = "https://login.microsoftonline.com/$Tenant" try { - $authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority + $authContext = New-Object 'Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext' -ArgumentList $authority - # https://msdn.microsoft.com/en-us/library/azure/microsoft.identitymodel.clients.activedirectory.promptbehavior.aspx - # Change the prompt behaviour to force credentials each time: Auto, Always, Never, RefreshSession + # https://msdn.microsoft.com/en-us/library/azure/microsoft.identitymodel.clients.activedirectory.promptbehavior.aspx + # Change the prompt behaviour to force credentials each time: Auto, Always, Never, RefreshSession - $platformParameters = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.PlatformParameters" -ArgumentList "Auto" + $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.UserIdentifier' -ArgumentList ($User, 'OptionalDisplayableId') - $authResult = $authContext.AcquireTokenAsync($resourceAppIdURI,$clientId,$redirectUri,$platformParameters,$userId).Result + $authResult = $authContext.AcquireTokenAsync($resourceAppIdURI, $clientId, $redirectUri, $platformParameters, $userId).Result # If the accesstoken is valid then create the authentication header - if($authResult.AccessToken){ + if ($authResult.AccessToken) { - # Creating header for Authorization token + # Creating header for Authorization token - $authHeader = @{ - 'Content-Type'='application/json' - 'Authorization'="Bearer " + $authResult.AccessToken - 'ExpiresOn'=$authResult.ExpiresOn + $authHeader = @{ + 'Content-Type' = 'application/json' + 'Authorization' = 'Bearer ' + $authResult.AccessToken + 'ExpiresOn' = $authResult.ExpiresOn } - return $authHeader + return $authHeader } else { - Write-Host - Write-Host "Authorization Access Token is null, please re-run authentication..." -ForegroundColor Red - Write-Host - break + Write-Host + Write-Host 'Authorization Access Token is null, please re-run authentication...' -ForegroundColor Red + Write-Host + break } @@ -154,10 +154,10 @@ $authority = "https://login.microsoftonline.com/$Tenant" catch { - write-host $_.Exception.Message -f Red - write-host $_.Exception.ItemName -f Red - write-host - break + Write-Host $_.Exception.Message -f Red + Write-Host $_.Exception.ItemName -f Red + Write-Host + break } @@ -165,9 +165,9 @@ $authority = "https://login.microsoftonline.com/$Tenant" #################################################### -Function Add-DeviceConfigurationPolicy(){ +Function Add-DeviceConfigurationPolicy() { -<# + <# .SYNOPSIS This function is used to add an device configuration policy using the Graph API REST interface .DESCRIPTION @@ -179,31 +179,31 @@ Adds a device configuration policy in Intune NAME: Add-DeviceConfigurationPolicy #> -[cmdletbinding()] + [CmdletBinding()] -param -( - $JSON -) + param + ( + $JSON + ) -$graphApiVersion = "Beta" -$DCP_resource = "deviceManagement/deviceConfigurations" -Write-Verbose "Resource: $DCP_resource" + $graphApiVersion = 'Beta' + $DCP_resource = 'deviceManagement/deviceConfigurations' + Write-Verbose "Resource: $DCP_resource" try { - if($JSON -eq "" -or $JSON -eq $null){ + if ([string]::IsNullOrWhiteSpace($JSON)) { - write-host "No JSON specified, please specify valid JSON for the Android Policy..." -f Red + Write-Host 'No JSON specified, please specify valid JSON for the Android Policy...' -f Red } else { - Test-JSON -JSON $JSON + Test-Json -Json $JSON - $uri = "https://graph.microsoft.com/$graphApiVersion/$($DCP_resource)" - Invoke-RestMethod -Uri $uri -Headers $authToken -Method Post -Body $JSON -ContentType "application/json" + $uri = "https://graph.microsoft.com/$graphApiVersion/$($DCP_resource)" + Invoke-RestMethod -Uri $uri -Headers $authToken -Method Post -Body $JSON -ContentType 'application/json' } @@ -211,16 +211,16 @@ Write-Verbose "Resource: $DCP_resource" 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 + $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 } @@ -228,9 +228,9 @@ Write-Verbose "Resource: $DCP_resource" #################################################### -Function Test-JSON(){ +Function Test-JSON() { -<# + <# .SYNOPSIS This function is used to test if the JSON passed to a REST Post request is valid .DESCRIPTION @@ -242,30 +242,30 @@ Test if the JSON is valid before calling the Graph REST interface NAME: Test-AuthHeader #> -param ( + param ( -$JSON + $JSON -) + ) try { - $TestJSON = ConvertFrom-Json $JSON -ErrorAction Stop - $validJson = $true + $TestJSON = ConvertFrom-Json $JSON -ErrorAction Stop + $validJson = $true } catch { - $validJson = $false - $_.Exception + $validJson = $false + $_.Exception } - if (!$validJson){ + if (!$validJson) { - Write-Host "Provided JSON isn't in valid JSON format" -f Red - break + Write-Host "Provided JSON isn't in valid JSON format" -f Red + break } @@ -274,7 +274,7 @@ $JSON #################################################### -Function Add-DeviceCompliancePolicybaseline(){ +Function Add-DeviceCompliancePolicybaseline() { <# .SYNOPSIS @@ -287,62 +287,62 @@ Function Add-DeviceCompliancePolicybaseline(){ .NOTES NAME: Add-DeviceCompliancePolicy #> - - [cmdletbinding()] - + + [CmdletBinding()] + param ( $JSON ) - - $graphApiVersion = "Beta" - $Resource = "deviceManagement/deviceCompliancePolicies" - - try { - - if($JSON -eq "" -or $JSON -eq $null){ - - write-host "No JSON specified, please specify valid JSON for the iOS Policy..." -f Red - - } - - else { - - Test-JSON -JSON $JSON - + + $graphApiVersion = 'Beta' + $Resource = 'deviceManagement/deviceCompliancePolicies' + + try { + + if ([string]::IsNullOrWhiteSpace($JSON)) { + + Write-Host 'No JSON specified, please specify valid JSON for the iOS Policy...' -f Red + + } + + else { + + Test-Json -Json $JSON + $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)" - Invoke-RestMethod -Uri $uri -Headers $authToken -Method Post -Body $JSON -ContentType "application/json" - - } - + Invoke-RestMethod -Uri $uri -Headers $authToken -Method Post -Body $JSON -ContentType 'application/json' + } - - catch { - + + } + + catch { + $ex = $_.Exception $errorResponse = $ex.Response.GetResponseStream() $reader = New-Object System.IO.StreamReader($errorResponse) $reader.BaseStream.Position = 0 $reader.DiscardBufferedData() - $responseBody = $reader.ReadToEnd(); + $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 + Write-Host break - - } - + } - - #################################################### + +} + +#################################################### #################################################### #region Authentication -write-host +Write-Host # Checking if authToken exists before running authentication -if($global:authToken){ +if ($global:authToken) { # Setting DateTime to Universal time to work in all timezones $DateTime = (Get-Date).ToUniversalTime() @@ -350,36 +350,36 @@ if($global:authToken){ # If the authToken exists checking when it expires $TokenExpires = ($authToken.ExpiresOn.datetime - $DateTime).Minutes - if($TokenExpires -le 0){ + if ($TokenExpires -le 0) { - write-host "Authentication Token expired" $TokenExpires "minutes ago" -ForegroundColor Yellow - write-host + Write-Host 'Authentication Token expired' $TokenExpires 'minutes ago' -ForegroundColor Yellow + Write-Host - # Defining User Principal Name if not present + # Defining User Principal Name if not present - if($User -eq $null -or $User -eq ""){ - $User = Read-Host -Prompt "Please specify your user principal name for Azure Authentication" + if ([string]::IsNullOrWhiteSpace($User)) { + $User = Read-Host -Prompt 'Please specify your user principal name for Azure Authentication' Write-Host - } + } $global:authToken = Get-AuthToken -User $User - } + } } # Authentication doesn't exist, calling Get-AuthToken function else { - if($User -eq $null -or $User -eq ""){ - $User = Read-Host -Prompt "Please specify your user principal name for Azure Authentication" - Write-Host + if ([string]::IsNullOrWhiteSpace($User)) { + $User = Read-Host -Prompt 'Please specify your user principal name for Azure Authentication' + Write-Host } -# Getting the authorization token -$global:authToken = Get-AuthToken -User $User + # Getting the authorization token + $global:authToken = Get-AuthToken -User $User } @@ -394,7 +394,7 @@ $global:authToken = Get-AuthToken -User $User #################################################### -$firewall = @" +$firewall = @' { @@ -703,12 +703,12 @@ $firewall = @" "blockCrossOrganizationWriteAccess": true } } -"@ +'@ #################################################### -$System1 = @" +$System1 = @' { "@odata.type": "#microsoft.graph.windows10GeneralConfiguration", @@ -1012,12 +1012,12 @@ $System1 = @" "severeSeverity": "quarantine" } } -"@ +'@ #################################################### #################################################### -$Baseline = @" +$Baseline = @' { "@odata.type": "#microsoft.graph.windows10CompliancePolicy", @@ -1059,7 +1059,7 @@ $Baseline = @" } -"@ +'@ #################################################### Add-DeviceConfigurationPolicy -Json $Firewall # OK diff --git a/Legacy/InstallMMAforApplocker.ps1 b/Legacy/InstallMMAforApplocker.ps1 index 9438da1..83d6791 100644 --- a/Legacy/InstallMMAforApplocker.ps1 +++ b/Legacy/InstallMMAforApplocker.ps1 @@ -1,8 +1,8 @@ <################################################################################################## # .SYNOPSIS -This script downloads, and installs the MMA agent (64 bit AMD processor). -The MMA agent provide the required monitoring of a device APPLOCKER instance. +This script downloads, and installs the MMA agent (64 bit AMD processor). +The MMA agent provide the required monitoring of a device APPLOCKER instance. This deployment is sample code to be used with the guidance at aka.ms/securedworkstation, using the Secure workstation profile. The Secure workstation profile once loaded in Intune will enable all targeted devices to beging auditing all @@ -19,8 +19,8 @@ generate large traffic to your Azure instance of your Log Analytics workspace. U Revised: Frank Simorjay Created: 05-09-2019 Revised: 05-09-2019 - Version: 1.0 - + Version: 1.0 + #> ################################################################################################### <# @@ -33,7 +33,7 @@ See LICENSE in the project root for license information. #################################################### -# Set the parameters for your installation. Note this sample targets the generic AMD64 bit MMA client. +# Set the parameters for your installation. Note this sample targets the generic AMD64 bit MMA client. $FileName = "MMASetup-AMD64.exe" $MMAFolder = 'C:\Source' #sample downloads the bits to this folder $MMALogsFolder = 'C:\MMAInstallLogs' #instal the bits and start logging activity of the installation effort - good for debugging @@ -54,7 +54,7 @@ Start-Transcript -Path $MMALogsFile -Append SC.EXE config AppIdSvc start= auto Write-Host "Configured AppIdSvc to auto start." -try +try { # Check to see if MMA is already installed. # This could happen if the customer already uses MMA or if we deployed this previously @@ -65,7 +65,7 @@ try $mma.AddCloudWorkspace($WorkSpaceID, $WorkSpaceKey) Exit 0 } -catch +catch { if ($MMAInstalled) { @@ -80,8 +80,8 @@ catch # Check if folder exists, if not, create it if (Test-Path $MMAFolder){ Write-Host "The folder $MMAFolder already exists." - } - else + } + else { Write-Host "The folder $MMAFolder does not exist, creating..." -NoNewline New-Item $MMAFolder -type Directory | Out-Null @@ -102,7 +102,7 @@ Set-Location $MMAFolder Invoke-WebRequest -Uri $URl -OutFile $MMAFile | Out-Null Write-Host "done!" -ForegroundColor Green } - + # Install the agent Write-Host "Installing Microsoft Monitoring Agent.." -nonewline $ArgumentList = '/C:"setup.exe /qn ADD_OPINSIGHTS_WORKSPACE=1 '+ "OPINSIGHTS_WORKSPACE_ID=$WorkspaceID " + "OPINSIGHTS_WORKSPACE_KEY=$WorkSpaceKey " +'AcceptEndUserLicenseAgreement=1"' @@ -115,8 +115,8 @@ Set-Location -Path "C:\" # Remove the folder with the agent if (-not (Test-Path $MMAFolder)) { Write-Host "The folder $MMAFolder does not exist." - } - else + } + else { Write-Host "Removing the folder $MMAFolder ..." -NoNewline Remove-Item $MMAFolder -Force -Recurse | Out-Null diff --git a/Legacy/README.md b/Legacy/README.md index 284e6d8..29e3be3 100644 --- a/Legacy/README.md +++ b/Legacy/README.md @@ -1,27 +1,24 @@ - -# LEGACY V1 - Secure Workstation configuration and policy baselines for Microsoft Intune and Windows RS5 +# LEGACY V1 - Secure Workstation configuration and policy baselines for Microsoft Intune and Windows RS5 **Content of this folder is provided as solution history...** Supporting document - https://aka.ms/securedworkstation +This site is a companion to the Secured Workstation providing the baseline for the 5 scenario levels outlined in document. -This site is a companion to the Secured Workstation providing the baseline for the 5 sceanrio levels outlined in document. - -These files are provided as samples, and a starting point to consider when you build your secured solution. +These files are provided as samples, and a starting point to consider when you build your secured solution. -**Note** The scripts have been tested in a EN-US enviroment only, as locality may impact international langugage packs. +**Note** The scripts have been tested in a EN-US environment only, as locality may impact international language packs. -# 6 sceanrios +# 6 scenarios 1. **Low Security** - No baseline provided 2. **Enhanced Security** - Enhanced Workstation - Windows10 (1809) .ps1 -3. **High Security** - High Security Workstation - Windows10 (1809) .ps1 +3. **High Security** - High Security Workstation - Windows10 (1809) .ps1 4. **Specialized** - Specialized workstation utilizes the [NCSC Security baseline](https://github.com/pelarsen/IntunePowerShellAutomation/blob/master/DeviceConfiguration_NCSC%20-%20Windows10%20(1803)%20SecurityBaseline.ps1) and the addition of the compliance enforcement script DeviceCompliance_NCSC-Windows10(1803).ps1 5. **Secured** - Secure Workstation - Windows10 (1809) SecurityBaseline (90).ps1 6. **Isolated** - No additional baseline provided +# MMA client installer -# MMA client installer - -The InstallMMAforApplocker.ps1 file will download and install MMA client for monitoring. This is part of the applocker monitoring provided in the Specialized, and Secured workstation sceanrios. The data will be uploaded to Log Analytics. +The InstallMMAforApplocker.ps1 file will download and install MMA client for monitoring. This is part of the AppLocker monitoring provided in the Specialized, and Secured workstation scenarios. The data will be uploaded to Log Analytics. diff --git a/Legacy/Secure-Workstation-Windows10-(1809)-SecurityBaseline.ps1 b/Legacy/Secure-Workstation-Windows10-(1809)-SecurityBaseline.ps1 index 5b358cb..d03deee 100644 --- a/Legacy/Secure-Workstation-Windows10-(1809)-SecurityBaseline.ps1 +++ b/Legacy/Secure-Workstation-Windows10-(1809)-SecurityBaseline.ps1 @@ -2,19 +2,19 @@ # .SYNOPSIS This is a script steps up the secure workstation enforcement. It moves the Enhanced baseline to full blocking security model -It is recommended to use the Ehanced baselie, and the -DeviceConfiguration_NCSC Baseline: https://www.ncsc.gov.uk/guidance/eud-guidance-windows-10-1803-mobile-device-management +It is recommended to use the Ehanced baselie, and the +DeviceConfiguration_NCSC Baseline: https://www.ncsc.gov.uk/guidance/eud-guidance-windows-10-1803-mobile-device-management prior to enabling this set of controls. THESE CONTROLS ARE EXTREAMLY RESTRICTIVE TO THE HOST. .NOTES FileName: Secure Workstation - Windows10 (1809) SecurityBaseline.ps1 - Author: Per Larsen + Author: Per Larsen Revised: Frank Simorjay Created: 03-09-2018 Revised: 05-09-2019 Version: 1.1 hardended - + #> ################################################################################################### <# @@ -29,7 +29,7 @@ See LICENSE in the project root for license information. function Get-AuthToken { -<# + <# .SYNOPSIS This function is used to authenticate with the Graph API REST interface .DESCRIPTION @@ -41,114 +41,114 @@ Authenticates you with the Graph API interface NAME: Get-AuthToken #> -[cmdletbinding()] + [CmdletBinding()] -param -( - [Parameter(Mandatory=$true)] - $User -) + param + ( + [Parameter(Mandatory = $true)] + $User + ) -$userUpn = New-Object "System.Net.Mail.MailAddress" -ArgumentList $User + $userUpn = New-Object 'System.Net.Mail.MailAddress' -ArgumentList $User -$tenant = $userUpn.Host + $tenant = $userUpn.Host -Write-Host "Checking for AzureAD module..." + Write-Host 'Checking for AzureAD module...' - $AadModule = Get-Module -Name "AzureAD" -ListAvailable + $AadModule = Get-Module -Name 'AzureAD' -ListAvailable if ($AadModule -eq $null) { - Write-Host "AzureAD PowerShell module not found, looking for AzureADPreview" - $AadModule = Get-Module -Name "AzureADPreview" -ListAvailable + Write-Host 'AzureAD PowerShell module not found, looking for AzureADPreview' + $AadModule = Get-Module -Name 'AzureADPreview' -ListAvailable } if ($AadModule -eq $null) { - write-host - write-host "AzureAD Powershell module not installed..." -f Red - write-host "Install by running 'Install-Module AzureAD' or 'Install-Module AzureADPreview' from an elevated PowerShell prompt" -f Yellow - write-host "Script can't continue..." -f Red - write-host + Write-Host + Write-Host 'AzureAD Powershell module not installed...' -f Red + Write-Host "Install by running 'Install-Module AzureAD' or 'Install-Module AzureADPreview' from an elevated PowerShell prompt" -f Yellow + Write-Host "Script can't continue..." -f Red + Write-Host exit } -# Getting path to ActiveDirectory Assemblies -# If the module count is greater than 1 find the latest version + # Getting path to ActiveDirectory Assemblies + # If the module count is greater than 1 find the latest version - if($AadModule.count -gt 1){ + if ($AadModule.count -gt 1) { - $Latest_Version = ($AadModule | select version | Sort-Object)[-1] + $Latest_Version = ($AadModule | Select-Object version | Sort-Object)[-1] - $aadModule = $AadModule | ? { $_.version -eq $Latest_Version.version } + $aadModule = $AadModule | Where-Object { $_.version -eq $Latest_Version.version } - # Checking if there are multiple versions of the same module found + # Checking if there are multiple versions of the same module found - if($AadModule.count -gt 1){ + if ($AadModule.count -gt 1) { - $aadModule = $AadModule | select -Unique + $aadModule = $AadModule | Select-Object -Unique - } + } - $adal = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.dll" - $adalforms = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll" + $adal = Join-Path $AadModule.ModuleBase 'Microsoft.IdentityModel.Clients.ActiveDirectory.dll' + $adalforms = Join-Path $AadModule.ModuleBase 'Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll' } else { - $adal = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.dll" - $adalforms = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll" + $adal = Join-Path $AadModule.ModuleBase 'Microsoft.IdentityModel.Clients.ActiveDirectory.dll' + $adalforms = Join-Path $AadModule.ModuleBase 'Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll' } -[System.Reflection.Assembly]::LoadFrom($adal) | Out-Null + [System.Reflection.Assembly]::LoadFrom($adal) | Out-Null -[System.Reflection.Assembly]::LoadFrom($adalforms) | Out-Null + [System.Reflection.Assembly]::LoadFrom($adalforms) | Out-Null -$clientId = "d1ddf0e4-d672-4dae-b554-9d5bdfd93547" + $clientId = 'd1ddf0e4-d672-4dae-b554-9d5bdfd93547' -$redirectUri = "urn:ietf:wg:oauth:2.0:oob" + $redirectUri = 'urn:ietf:wg:oauth:2.0:oob' -$resourceAppIdURI = "https://graph.microsoft.com" + $resourceAppIdURI = 'https://graph.microsoft.com' -$authority = "https://login.microsoftonline.com/$Tenant" + $authority = "https://login.microsoftonline.com/$Tenant" try { - $authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority + $authContext = New-Object 'Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext' -ArgumentList $authority - # https://msdn.microsoft.com/en-us/library/azure/microsoft.identitymodel.clients.activedirectory.promptbehavior.aspx - # Change the prompt behaviour to force credentials each time: Auto, Always, Never, RefreshSession + # https://msdn.microsoft.com/en-us/library/azure/microsoft.identitymodel.clients.activedirectory.promptbehavior.aspx + # Change the prompt behaviour to force credentials each time: Auto, Always, Never, RefreshSession - $platformParameters = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.PlatformParameters" -ArgumentList "Auto" + $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.UserIdentifier' -ArgumentList ($User, 'OptionalDisplayableId') - $authResult = $authContext.AcquireTokenAsync($resourceAppIdURI,$clientId,$redirectUri,$platformParameters,$userId).Result + $authResult = $authContext.AcquireTokenAsync($resourceAppIdURI, $clientId, $redirectUri, $platformParameters, $userId).Result # If the accesstoken is valid then create the authentication header - if($authResult.AccessToken){ + if ($authResult.AccessToken) { - # Creating header for Authorization token + # Creating header for Authorization token - $authHeader = @{ - 'Content-Type'='application/json' - 'Authorization'="Bearer " + $authResult.AccessToken - 'ExpiresOn'=$authResult.ExpiresOn + $authHeader = @{ + 'Content-Type' = 'application/json' + 'Authorization' = 'Bearer ' + $authResult.AccessToken + 'ExpiresOn' = $authResult.ExpiresOn } - return $authHeader + return $authHeader } else { - Write-Host - Write-Host "Authorization Access Token is null, please re-run authentication..." -ForegroundColor Red - Write-Host - break + Write-Host + Write-Host 'Authorization Access Token is null, please re-run authentication...' -ForegroundColor Red + Write-Host + break } @@ -156,10 +156,10 @@ $authority = "https://login.microsoftonline.com/$Tenant" catch { - write-host $_.Exception.Message -f Red - write-host $_.Exception.ItemName -f Red - write-host - break + Write-Host $_.Exception.Message -f Red + Write-Host $_.Exception.ItemName -f Red + Write-Host + break } @@ -167,9 +167,9 @@ $authority = "https://login.microsoftonline.com/$Tenant" #################################################### -Function Add-DeviceConfigurationPolicy(){ +Function Add-DeviceConfigurationPolicy() { -<# + <# .SYNOPSIS This function is used to add an device configuration policy using the Graph API REST interface .DESCRIPTION @@ -181,31 +181,31 @@ Adds a device configuration policy in Intune NAME: Add-DeviceConfigurationPolicy #> -[cmdletbinding()] + [CmdletBinding()] -param -( - $JSON -) + param + ( + $JSON + ) -$graphApiVersion = "Beta" -$DCP_resource = "deviceManagement/deviceConfigurations" -Write-Verbose "Resource: $DCP_resource" + $graphApiVersion = 'Beta' + $DCP_resource = 'deviceManagement/deviceConfigurations' + Write-Verbose "Resource: $DCP_resource" try { - if($JSON -eq "" -or $JSON -eq $null){ + if ([string]::IsNullOrWhiteSpace($JSON)) { - write-host "No JSON specified, please specify valid JSON for the Android Policy..." -f Red + Write-Host 'No JSON specified, please specify valid JSON for the Android Policy...' -f Red } else { - Test-JSON -JSON $JSON + Test-Json -Json $JSON - $uri = "https://graph.microsoft.com/$graphApiVersion/$($DCP_resource)" - Invoke-RestMethod -Uri $uri -Headers $authToken -Method Post -Body $JSON -ContentType "application/json" + $uri = "https://graph.microsoft.com/$graphApiVersion/$($DCP_resource)" + Invoke-RestMethod -Uri $uri -Headers $authToken -Method Post -Body $JSON -ContentType 'application/json' } @@ -213,16 +213,16 @@ Write-Verbose "Resource: $DCP_resource" 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 + $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 } @@ -230,9 +230,9 @@ Write-Verbose "Resource: $DCP_resource" #################################################### -Function Test-JSON(){ +Function Test-JSON() { -<# + <# .SYNOPSIS This function is used to test if the JSON passed to a REST Post request is valid .DESCRIPTION @@ -244,30 +244,30 @@ Test if the JSON is valid before calling the Graph REST interface NAME: Test-AuthHeader #> -param ( + param ( -$JSON + $JSON -) + ) try { - $TestJSON = ConvertFrom-Json $JSON -ErrorAction Stop - $validJson = $true + $TestJSON = ConvertFrom-Json $JSON -ErrorAction Stop + $validJson = $true } catch { - $validJson = $false - $_.Exception + $validJson = $false + $_.Exception } - if (!$validJson){ + if (!$validJson) { - Write-Host "Provided JSON isn't in valid JSON format" -f Red - break + Write-Host "Provided JSON isn't in valid JSON format" -f Red + break } @@ -276,7 +276,7 @@ $JSON #################################################### -Function Add-DeviceCompliancePolicybaseline(){ +Function Add-DeviceCompliancePolicybaseline() { <# .SYNOPSIS @@ -289,62 +289,62 @@ Function Add-DeviceCompliancePolicybaseline(){ .NOTES NAME: Add-DeviceCompliancePolicy #> - - [cmdletbinding()] - + + [CmdletBinding()] + param ( $JSON ) - - $graphApiVersion = "Beta" - $Resource = "deviceManagement/deviceCompliancePolicies" - - try { - - if($JSON -eq "" -or $JSON -eq $null){ - - write-host "No JSON specified, please specify valid JSON for the iOS Policy..." -f Red - - } - - else { - - Test-JSON -JSON $JSON - + + $graphApiVersion = 'Beta' + $Resource = 'deviceManagement/deviceCompliancePolicies' + + try { + + if ([string]::IsNullOrWhiteSpace($JSON)) { + + Write-Host 'No JSON specified, please specify valid JSON for the iOS Policy...' -f Red + + } + + else { + + Test-Json -Json $JSON + $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)" - Invoke-RestMethod -Uri $uri -Headers $authToken -Method Post -Body $JSON -ContentType "application/json" - - } - + Invoke-RestMethod -Uri $uri -Headers $authToken -Method Post -Body $JSON -ContentType 'application/json' + } - - catch { - + + } + + catch { + $ex = $_.Exception $errorResponse = $ex.Response.GetResponseStream() $reader = New-Object System.IO.StreamReader($errorResponse) $reader.BaseStream.Position = 0 $reader.DiscardBufferedData() - $responseBody = $reader.ReadToEnd(); + $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 + Write-Host break - - } - + } - - #################################################### + +} + +#################################################### #################################################### #region Authentication -write-host +Write-Host # Checking if authToken exists before running authentication -if($global:authToken){ +if ($global:authToken) { # Setting DateTime to Universal time to work in all timezones $DateTime = (Get-Date).ToUniversalTime() @@ -352,36 +352,36 @@ if($global:authToken){ # If the authToken exists checking when it expires $TokenExpires = ($authToken.ExpiresOn.datetime - $DateTime).Minutes - if($TokenExpires -le 0){ + if ($TokenExpires -le 0) { - write-host "Authentication Token expired" $TokenExpires "minutes ago" -ForegroundColor Yellow - write-host + Write-Host 'Authentication Token expired' $TokenExpires 'minutes ago' -ForegroundColor Yellow + Write-Host - # Defining User Principal Name if not present + # Defining User Principal Name if not present - if($User -eq $null -or $User -eq ""){ - $User = Read-Host -Prompt "Please specify your user principal name for Azure Authentication" + if ([string]::IsNullOrWhiteSpace($User)) { + $User = Read-Host -Prompt 'Please specify your user principal name for Azure Authentication' Write-Host - } + } $global:authToken = Get-AuthToken -User $User - } + } } # Authentication doesn't exist, calling Get-AuthToken function else { - if($User -eq $null -or $User -eq ""){ - $User = Read-Host -Prompt "Please specify your user principal name for Azure Authentication" - Write-Host + if ([string]::IsNullOrWhiteSpace($User)) { + $User = Read-Host -Prompt 'Please specify your user principal name for Azure Authentication' + Write-Host } -# Getting the authorization token -$global:authToken = Get-AuthToken -User $User + # Getting the authorization token + $global:authToken = Get-AuthToken -User $User } @@ -391,7 +391,7 @@ $global:authToken = Get-AuthToken -User $User #################################################### #Jason Components #################################################### -$Applocker = @" +$Applocker = @' { "@odata.type": "#microsoft.graph.windows10CustomConfiguration", @@ -444,12 +444,12 @@ $Applocker = @" ] } -"@ +'@ #################################################### -$firewall = @" +$firewall = @' { @@ -774,12 +774,12 @@ $firewall = @" "blockCrossOrganizationWriteAccess": true } } -"@ +'@ #################################################### -$System1 = @" +$System1 = @' { "@odata.type": "#microsoft.graph.windows10GeneralConfiguration", @@ -897,7 +897,7 @@ $System1 = @" "defenderScheduledScanTime": null, "defenderScheduledQuickScanTime": "23:00:00", - + "defenderCloudBlockLevel": "notConfigured", "defenderCloudExtendedTimeout": null, "defenderCloudExtendedTimeoutInSeconds": null, @@ -918,7 +918,7 @@ $System1 = @" "passwordMinimumCharacterSetCount": null, "passwordPreviousPasswordBlockCount": 21, - + "passwordRequired": true, "passwordRequireWhenResumeFromIdleState": true, "passwordRequiredType": "deviceDefault", @@ -990,7 +990,7 @@ $System1 = @" "cortanaBlocked": true, "deviceManagementBlockFactoryResetOnMobile": false, "deviceManagementBlockManualUnenroll": true, - + "safeSearchFilter": "strict", "edgeBlockPopups": true, @@ -1049,10 +1049,10 @@ $System1 = @" "appManagementMSIAllowUserControlOverInstall": false, "appManagementMSIAlwaysInstallWithElevatedPrivileges": false } -"@ +'@ #################################################### -$System2 = @" +$System2 = @' { "@odata.type": "#microsoft.graph.windows10CustomConfiguration", @@ -1231,7 +1231,7 @@ $System2 = @" "omaUri": "./Device/Vendor/MSFT/Policy/Config/MSSecurityGuide/EnableStructuredExceptionHandlingOverwriteProtection", "value": "\u003cenabled/\u003e" }, - + { "@odata.type": "#microsoft.graph.omaSettingString", "displayName": "MS Security Guide - WDigest Authentication", @@ -1326,10 +1326,10 @@ $System2 = @" } ] } -"@ +'@ #################################################### -$User = @" +$User = @' { "@odata.type": "#microsoft.graph.windows10CustomConfiguration", @@ -1349,11 +1349,11 @@ $User = @" ] } -"@ +'@ #################################################### #################################################### -$Baseline = @" +$Baseline = @' { "@odata.type": "#microsoft.graph.windows10CompliancePolicy", @@ -1395,7 +1395,7 @@ $Baseline = @" } -"@ +'@ #################################################### Add-DeviceConfigurationPolicy -Json $Applocker # OK diff --git a/PAW/Import-DeviceConfigScript.ps1 b/PAW/Import-DeviceConfigScript.ps1 index 5e7137b..b616fb4 100644 --- a/PAW/Import-DeviceConfigScript.ps1 +++ b/PAW/Import-DeviceConfigScript.ps1 @@ -7,7 +7,7 @@ See LICENSE in the project root for license information. #> $ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path -$ImportPath = $ScriptDir+"\Scripts\PAW-DeviceConfig.ps1" +$ImportPath = $ScriptDir + '\Scripts\PAW-DeviceConfig.ps1' #################################################### @@ -25,7 +25,7 @@ Authenticates you with the Graph API interface NAME: Get-AuthToken #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -33,27 +33,24 @@ NAME: Get-AuthToken $User ) - $userUpn = New-Object "System.Net.Mail.MailAddress" -ArgumentList $User + $userUpn = New-Object 'System.Net.Mail.MailAddress' -ArgumentList $User $tenant = $userUpn.Host - Write-Host "Checking for AzureADPreview module..." + Write-Host 'Checking for AzureADPreview module...' - $AadModule = Get-Module -Name "AzureADPreview" -ListAvailable + $AadModule = Get-Module -Name 'AzureADPreview' -ListAvailable - if ($AadModule -eq $null) { + if ($null -eq $AadModule) { - Write-Host "AzureAD PowerShell module not found, looking for AzureADPreview" - $AadModule = Get-Module -Name "AzureADPreview" -ListAvailable + Write-Host 'AzureAD PowerShell module not found, looking for AzureADPreview' + $AadModule = Get-Module -Name 'AzureADPreview' -ListAvailable - } - - if ($AadModule -eq $null) { - write-host - write-host "AzureAD Powershell module not installed..." -f Red - write-host "Install by running 'Install-Module AzureAD' or 'Install-Module AzureADPreview' from an elevated PowerShell prompt" -f Yellow - write-host "Script can't continue..." -f Red - write-host + Write-Host + Write-Host 'AzureAD Powershell module not installed...' -f Red + Write-Host "Install by running 'Install-Module AzureAD' or 'Install-Module AzureADPreview' from an elevated PowerShell prompt" -f Yellow + Write-Host "Script can't continue..." -f Red + Write-Host exit } @@ -62,27 +59,27 @@ NAME: Get-AuthToken if ($AadModule.count -gt 1) { - $Latest_Version = ($AadModule | select version | Sort-Object)[-1] + $Latest_Version = ($AadModule | Select-Object version | Sort-Object)[-1] - $aadModule = $AadModule | ? { $_.version -eq $Latest_Version.version } + $aadModule = $AadModule | Where-Object { $_.version -eq $Latest_Version.version } # Checking if there are multiple versions of the same module found if ($AadModule.count -gt 1) { - $aadModule = $AadModule | select -Unique + $aadModule = $AadModule | Select-Object -Unique } - $adal = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.dll" - $adalforms = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll" + $adal = Join-Path $AadModule.ModuleBase 'Microsoft.IdentityModel.Clients.ActiveDirectory.dll' + $adalforms = Join-Path $AadModule.ModuleBase 'Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll' } else { - $adal = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.dll" - $adalforms = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll" + $adal = Join-Path $AadModule.ModuleBase 'Microsoft.IdentityModel.Clients.ActiveDirectory.dll' + $adalforms = Join-Path $AadModule.ModuleBase 'Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll' } @@ -90,24 +87,24 @@ NAME: Get-AuthToken [System.Reflection.Assembly]::LoadFrom($adalforms) | Out-Null - $clientId = "d1ddf0e4-d672-4dae-b554-9d5bdfd93547" + $clientId = 'd1ddf0e4-d672-4dae-b554-9d5bdfd93547' - $redirectUri = "urn:ietf:wg:oauth:2.0:oob" + $redirectUri = 'urn:ietf:wg:oauth:2.0:oob' - $resourceAppIdURI = "https://graph.microsoft.com" + $resourceAppIdURI = 'https://graph.microsoft.com' $authority = "https://login.microsoftonline.com/$Tenant" try { - $authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority + $authContext = New-Object 'Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext' -ArgumentList $authority # https://msdn.microsoft.com/en-us/library/azure/microsoft.identitymodel.clients.activedirectory.promptbehavior.aspx # Change the prompt behaviour to force credentials each time: Auto, Always, Never, RefreshSession - $platformParameters = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.PlatformParameters" -ArgumentList "Auto" + $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.UserIdentifier' -ArgumentList ($User, 'OptionalDisplayableId') $authResult = $authContext.AcquireTokenAsync($resourceAppIdURI, $clientId, $redirectUri, $platformParameters, $userId).Result @@ -119,7 +116,7 @@ NAME: Get-AuthToken $authHeader = @{ 'Content-Type' = 'application/json' - 'Authorization' = "Bearer " + $authResult.AccessToken + 'Authorization' = 'Bearer ' + $authResult.AccessToken 'ExpiresOn' = $authResult.ExpiresOn } @@ -130,7 +127,7 @@ NAME: Get-AuthToken else { Write-Host - Write-Host "Authorization Access Token is null, please re-run authentication..." -ForegroundColor Red + Write-Host 'Authorization Access Token is null, please re-run authentication...' -ForegroundColor Red Write-Host break @@ -140,9 +137,9 @@ NAME: Get-AuthToken catch { - write-host $_.Exception.Message -f Red - write-host $_.Exception.ItemName -f Red - write-host + Write-Host $_.Exception.Message -f Red + Write-Host $_.Exception.ItemName -f Red + Write-Host break } @@ -165,7 +162,7 @@ Adds a device management script from a URL in Intune .NOTES NAME: Add-DeviceManagementScript #> - [cmdletbinding()] + [CmdletBinding()] Param ( # Path or URL to Powershell-script to add to Intune [Parameter(Mandatory = $true)] @@ -178,7 +175,7 @@ NAME: Add-DeviceManagementScript [switch][bool]$URL = $false ) if ($URL -eq $true) { - $FileName = $File -split "/" + $FileName = $File -split '/' $FileName = $FileName[-1] $OutFile = "$env:TEMP\$FileName" try { @@ -201,7 +198,7 @@ NAME: Add-DeviceManagementScript } $FileName = Get-Item $File | Select-Object -ExpandProperty Name } - $B64File = [System.Convert]::ToBase64String([System.IO.File]::ReadAllBytes("$File")); + $B64File = [System.Convert]::ToBase64String([System.IO.File]::ReadAllBytes("$File")) if ($URL -eq $true) { Remove-Item $File -Force @@ -223,13 +220,13 @@ NAME: Add-DeviceManagementScript } "@ - $graphApiVersion = "Beta" - $DMS_resource = "deviceManagement/deviceManagementScripts" + $graphApiVersion = 'Beta' + $DMS_resource = 'deviceManagement/deviceManagementScripts' Write-Verbose "Resource: $DMS_resource" try { $uri = "https://graph.microsoft.com/$graphApiVersion/$DMS_resource" - Invoke-RestMethod -Uri $uri -Headers $authToken -Method Post -Body $JSON -ContentType "application/json" + Invoke-RestMethod -Uri $uri -Headers $authToken -Method Post -Body $JSON -ContentType 'application/json' } catch { @@ -239,10 +236,10 @@ NAME: Add-DeviceManagementScript $reader = New-Object System.IO.StreamReader($errorResponse) $reader.BaseStream.Position = 0 $reader.DiscardBufferedData() - $responseBody = $reader.ReadToEnd(); + $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 + Write-Host break } @@ -264,7 +261,7 @@ Adds a device configuration policy assignment in Intune NAME: Add-DeviceConfigurationPolicyAssignment #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -272,21 +269,21 @@ NAME: Add-DeviceConfigurationPolicyAssignment $TargetGroupId ) - $graphApiVersion = "Beta" + $graphApiVersion = 'Beta' $Resource = "deviceManagement/deviceManagementScripts/$ScriptId/assign" try { if (!$ScriptId) { - write-host "No Script Policy Id specified, specify a valid Script Policy Id" -f Red + Write-Host 'No Script Policy Id specified, specify a valid Script Policy Id' -f Red break } if (!$TargetGroupId) { - write-host "No Target Group Id specified, specify a valid Target Group Id" -f Red + Write-Host 'No Target Group Id specified, specify a valid Target Group Id' -f Red break } @@ -304,7 +301,7 @@ NAME: Add-DeviceConfigurationPolicyAssignment "@ $uri = "https://graph.microsoft.com/$graphApiVersion/$Resource" - Invoke-RestMethod -Uri $uri -Headers $authToken -Method Post -Body $JSON -ContentType "application/json" + Invoke-RestMethod -Uri $uri -Headers $authToken -Method Post -Body $JSON -ContentType 'application/json' } @@ -315,10 +312,10 @@ NAME: Add-DeviceConfigurationPolicyAssignment $reader = New-Object System.IO.StreamReader($errorResponse) $reader.BaseStream.Position = 0 $reader.DiscardBufferedData() - $responseBody = $reader.ReadToEnd(); + $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 + Write-Host break } @@ -340,7 +337,7 @@ Returns all users registered with Azure AD NAME: Get-AADGroup #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -350,8 +347,8 @@ NAME: Get-AADGroup ) # Defining Variables - $graphApiVersion = "v1.0" - $Group_resource = "groups" + $graphApiVersion = 'v1.0' + $Group_resource = 'groups' try { @@ -362,7 +359,7 @@ NAME: Get-AADGroup } - elseif ($GroupName -eq "" -or $GroupName -eq $null) { + elseif ([string]::IsNullOrWhiteSpace($GroupName)) { $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)" (Invoke-RestMethod -Uri $uri -Headers $authToken -Method Get).Value @@ -388,7 +385,7 @@ NAME: Get-AADGroup $GID = $Group.id $Group.displayName - write-host + Write-Host $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)/$GID/Members" (Invoke-RestMethod -Uri $uri -Headers $authToken -Method Get).Value @@ -406,10 +403,10 @@ NAME: Get-AADGroup $reader = New-Object System.IO.StreamReader($errorResponse) $reader.BaseStream.Position = 0 $reader.DiscardBufferedData() - $responseBody = $reader.ReadToEnd(); + $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 + Write-Host break } @@ -421,7 +418,7 @@ NAME: Get-AADGroup #region Authentication -write-host +Write-Host # Checking if authToken exists before running authentication if ($global:authToken) { @@ -434,14 +431,14 @@ if ($global:authToken) { if ($TokenExpires -le 0) { - write-host "Authentication Token expired" $TokenExpires "minutes ago" -ForegroundColor Yellow - write-host + Write-Host 'Authentication Token expired' $TokenExpires 'minutes ago' -ForegroundColor Yellow + Write-Host # Defining User Principal Name if not present - if ($User -eq $null -or $User -eq "") { + if ([string]::IsNullOrWhiteSpace($User)) { - $User = Read-Host -Prompt "Please specify your user principal name for Azure Authentication" + $User = Read-Host -Prompt 'Please specify your user principal name for Azure Authentication' Write-Host } @@ -455,9 +452,9 @@ if ($global:authToken) { else { - if ($User -eq $null -or $User -eq "") { + if ([string]::IsNullOrWhiteSpace($User)) { - $User = Read-Host -Prompt "Please specify your user principal name for Azure Authentication" + $User = Read-Host -Prompt 'Please specify your user principal name for Azure Authentication' Write-Host } @@ -474,12 +471,12 @@ else { # Setting application AAD Group to assign PowerShell scripts #$AADGroup = Read-Host -Prompt "Enter the Azure AD Group name where PowerShell scripts will be assigned" -$AADGroup = "Privileged Workstations" +$AADGroup = 'Privileged Workstations' $TargetGroupId = (Get-AADGroup -GroupName "$AADGroup").id -if ($TargetGroupId -eq $null -or $TargetGroupId -eq "") { +if ([string]::IsNullOrWhiteSpace($TargetGroupId)) { Write-Host "AAD Group - '$AADGroup' doesn't exist, please specify a valid AAD Group..." -ForegroundColor Red Write-Host @@ -489,13 +486,13 @@ if ($TargetGroupId -eq $null -or $TargetGroupId -eq "") { #################################################### -Write-Host "Adding Device Configuration Script from " $ImportPath -ForegroundColor Green +Write-Host 'Adding Device Configuration Script from ' $ImportPath -ForegroundColor Green -$Create_Local_Script = Add-DeviceManagementScript -File $ImportPath -Description "PAW Device Config script" +$Create_Local_Script = Add-DeviceManagementScript -File $ImportPath -Description 'PAW Device Config script' -Write-Host "Device Management Script created as" $Create_Local_Script.id -write-host -write-host "Assigning Device Management Script to AAD Group '$AADGroup'" -f Cyan +Write-Host 'Device Management Script created as' $Create_Local_Script.id +Write-Host +Write-Host "Assigning Device Management Script to AAD Group '$AADGroup'" -f Cyan $Assign_Local_Script = Add-DeviceManagementScriptAssignment -ScriptId $Create_Local_Script.id -TargetGroupId $TargetGroupId diff --git a/PAW/Import-PAW-DeviceCompliancePolicies.ps1 b/PAW/Import-PAW-DeviceCompliancePolicies.ps1 index 00ef5fb..fd31991 100644 --- a/PAW/Import-PAW-DeviceCompliancePolicies.ps1 +++ b/PAW/Import-PAW-DeviceCompliancePolicies.ps1 @@ -7,8 +7,7 @@ See LICENSE in the project root for license information. #> $ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path -$ImportPath = $ScriptDir + "\JSON\DeviceCompliance" - +$ImportPath = $ScriptDir + '\JSON\DeviceCompliance' #################################################### @@ -26,7 +25,7 @@ Authenticates you with the Graph API interface NAME: Test-MgAuth #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -34,21 +33,21 @@ NAME: Test-MgAuth $User ) - $userUpn = New-Object "System.Net.Mail.MailAddress" -ArgumentList $User + $userUpn = New-Object 'System.Net.Mail.MailAddress' -ArgumentList $User $tenant = $userUpn.Host - Write-Host "Checking for Microsoft Graph module..." + Write-Host 'Checking for Microsoft Graph module...' - $MgModule = Get-Module -Name "Microsoft.Graph" -ListAvailable + $MgModule = Get-Module -Name 'Microsoft.Graph' -ListAvailable if ($null -eq $MgModule) { - write-host - write-host "Microsoft Graph Powershell module not installed..." -f Red - write-host "Install by running 'Install-Module Microsoft.Graph' or 'Install-Module Microsoft.Graph' from an elevated PowerShell prompt" -f Yellow - write-host "Script can't continue..." -f Red - write-host - + Write-Host + Write-Host 'Microsoft Graph Powershell module not installed...' -f Red + Write-Host "Install by running 'Install-Module Microsoft.Graph' or 'Install-Module Microsoft.Graph' from an elevated PowerShell prompt" -f Yellow + Write-Host "Script can't continue..." -f Red + Write-Host + } $scopes = @() @@ -56,20 +55,20 @@ NAME: Test-MgAuth ######################################### # Directory related scopes # ######################################### - $scopes += @("Device.Read.All", - "User.Read.All", - "GroupMember.ReadWrite.All", - "Group.ReadWrite.All", - "Directory.ReadWrite.All") + $scopes += @('Device.Read.All', + 'User.Read.All', + 'GroupMember.ReadWrite.All', + 'Group.ReadWrite.All', + 'Directory.ReadWrite.All') ######################################### # Device Management scopes # ######################################### - $scopes += @("DeviceManagementConfiguration.ReadWrite.All", - "DeviceManagementServiceConfig.ReadWrite.All", - "DeviceManagementRBAC.ReadWrite.All", - "DeviceManagementManagedDevices.ReadWrite.All", - "DeviceManagementApps.ReadWrite.All") + $scopes += @('DeviceManagementConfiguration.ReadWrite.All', + 'DeviceManagementServiceConfig.ReadWrite.All', + 'DeviceManagementRBAC.ReadWrite.All', + 'DeviceManagementManagedDevices.ReadWrite.All', + 'DeviceManagementApps.ReadWrite.All') #$clientId = "d1ddf0e4-d672-4dae-b554-9d5bdfd93547" @@ -84,11 +83,11 @@ NAME: Test-MgAuth $ctx = Get-MgContext $org = Get-MgOrganization - $domains = $org.VerifiedDomains | select-object -ExpandProperty Name + $domains = $org.VerifiedDomains | Select-Object -ExpandProperty Name if ($ctx.Account.ToLower() -ne $userUpn.Address.ToLower() -or ($ctx.TenantId -ne $org.Id) -or $domains -notcontains $tenant) { - write-host "Unable to verify tenant or account" -f Red + Write-Host 'Unable to verify tenant or account' -f Red Disconnect-MgGraph - throw "Unable to continue due to validation" + throw 'Unable to continue due to validation' } # $authHeader = @{ @@ -100,13 +99,12 @@ NAME: Test-MgAuth # return $authHeader } catch { - write-host $_.Exception.Message -f Red - write-host $_.Exception.ItemName -f Red - write-host + Write-Host $_.Exception.Message -f Red + Write-Host $_.Exception.ItemName -f Red + Write-Host break } - } #################################################### @@ -124,46 +122,42 @@ Function Add-DeviceCompliancePolicy() { .NOTES NAME: Add-DeviceCompliancePolicy #> - - [cmdletbinding()] - + + [CmdletBinding()] + param ( $JSON ) - - $graphApiVersion = "Beta" - $Resource = "deviceManagement/deviceCompliancePolicies" - + + $graphApiVersion = 'Beta' + $Resource = 'deviceManagement/deviceCompliancePolicies' + try { - - if ($JSON -eq "" -or $null -eq $JSON) { - - write-host "No JSON specified, please specify valid JSON for the iOS Policy..." -f Red - + + if ([string]::IsNullOrWhiteSpace($JSON)) { + Write-Host 'No JSON specified, please specify valid JSON for the iOS Policy...' -ForegroundColor Red } - + else { - - Test-JSON -JSON $JSON - + + Test-Json -Json $JSON + $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)" - Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType "application/json" + Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType 'application/json' } } catch { $ex = $_.Exception - Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break } } - -#################################################### +#################################################### Function Get-AADGroup() { @@ -179,7 +173,7 @@ Returns all users registered with Azure AD NAME: Get-AADGroup #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -189,11 +183,11 @@ NAME: Get-AADGroup ) # Defining Variables - $graphApiVersion = "v1.0" - $Group_resource = "groups" + $graphApiVersion = 'v1.0' + $Group_resource = 'groups' # pseudo-group identifiers for all users and all devices - [string]$AllUsers = "acacacac-9df4-4c7d-9d50-4ef0226f57a9" - [string]$AllDevices = "adadadad-808e-44e2-905a-0b7873a8a531" + [string]$AllUsers = 'acacacac-9df4-4c7d-9d50-4ef0226f57a9' + [string]$AllDevices = 'adadadad-808e-44e2-905a-0b7873a8a531' try { @@ -201,14 +195,13 @@ NAME: Get-AADGroup $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)?`$filter=id eq '$id'" switch ( $id ) { - $AllUsers { $grp = [PSCustomObject]@{ displayName = "All users" }; $grp } - $AllDevices { $grp = [PSCustomObject]@{ displayName = "All devices" }; $grp } + $AllUsers { $grp = [PSCustomObject]@{ displayName = 'All users' }; $grp } + $AllDevices { $grp = [PSCustomObject]@{ displayName = 'All devices' }; $grp } default { (Invoke-MgGraphRequest -Uri $uri -Method Get).Value } } - } - elseif ($GroupName -eq "" -or $null -eq $GroupName) { + elseif ([string]::IsNullOrWhiteSpace($GroupName)) { $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)" (Invoke-MgGraphRequest -Uri $uri -Method Get).Value @@ -234,31 +227,26 @@ NAME: Get-AADGroup $GID = $Group.id $Group.displayName - write-host + Write-Host $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)/$GID/Members" (Invoke-MgGraphRequest -Uri $uri -Method Get).Value } - } - } - } catch { $ex = $_.Exception - Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break } - } #################################################### @@ -279,38 +267,34 @@ Function Get-DeviceCompliancePolicy() { .NOTES NAME: Get-DeviceCompliancePolicy #> - - [cmdletbinding()] - + + [CmdletBinding()] + param ( $Name ) - $graphApiVersion = "Beta" - $Resource = "deviceManagement/deviceCompliancePolicies" - + $graphApiVersion = 'Beta' + $Resource = 'deviceManagement/deviceCompliancePolicies' + try { - + $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)" - (Invoke-MgGraphRequest -Uri $uri -Method Get).Value | Where-Object { ($_.'@odata.type').contains("windows10CompliancePolicy") -and ($_.'displayName').contains($Name) } - + (Invoke-MgGraphRequest -Uri $uri -Method Get).Value | Where-Object { ($_.'@odata.type').contains('windows10CompliancePolicy') -and ($_.'displayName').contains($Name) } + } - + catch { - + $ex = $_.Exception - Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break - + } - } - - #################################################### @@ -327,34 +311,33 @@ Function Add-DeviceCompliancePolicyAssignment() { .NOTES NAME: Add-DeviceCompliancePolicyAssignment #> - - [cmdletbinding()] - + + [CmdletBinding()] + param ( $CompliancePolicyId, $ComplianceAssignments ) - - $graphApiVersion = "v1.0" + + $graphApiVersion = 'v1.0' $Resource = "deviceManagement/deviceCompliancePolicies/$CompliancePolicyId/assign" - + try { - + if (!$CompliancePolicyId) { - - write-host "No Compliance Policy Id specified, specify a valid Compliance Policy Id" -f Red + + Write-Host 'No Compliance Policy Id specified, specify a valid Compliance Policy Id' -f Red break - } - + if (!$ComplianceAssignments) { - write-host "No Target Group Id specified, specify a valid Target Group Id" -f Red + Write-Host 'No Target Group Id specified, specify a valid Target Group Id' -f Red break - + } - + $JSON = @" { @@ -367,24 +350,22 @@ Function Add-DeviceCompliancePolicyAssignment() { Write-Output $JSON $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)" - Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType "application/json" - - + Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType 'application/json' + } - + catch { - + $ex = $_.Exception - Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break } - + } - + #################################################### Function Test-JSON() { @@ -402,45 +383,39 @@ NAME: Test-AuthHeader #> param ( - $JSON - ) try { - $TestJSON = ConvertFrom-Json $JSON -ErrorAction Stop + $null = ConvertFrom-Json $JSON -ErrorAction Stop $validJson = $true - } catch { $validJson = $false $_.Exception - } if (!$validJson) { - + Write-Host "Provided JSON isn't in valid JSON format" -f Red break } - } #################################################### #region Authentication -write-host +Write-Host -if ($null -eq $User -or $User -eq "") { +if ([string]::IsNullOrWhiteSpace($User)) { - $User = Read-Host -Prompt "Please specify your user principal name for Azure Authentication" + $User = Read-Host -Prompt 'Please specify your user principal name for Azure Authentication' Write-Host - } Test-MgAuth -User $User @@ -463,10 +438,10 @@ if (!(Test-Path "$ImportPath")) { #################################################### -Get-ChildItem $ImportPath -filter *.json | -Foreach-object { +Get-ChildItem $ImportPath -Filter *.json | +ForEach-Object { - $JSON_Data = Get-Content $_.FullName | Where-Object { $_ -notmatch "scheduledActionConfigurations@odata.context" } + $JSON_Data = Get-Content $_.FullName | Where-Object { $_ -notmatch 'scheduledActionConfigurations@odata.context' } # Excluding entries that are not required - id,createdDateTime,lastModifiedDateTime,version $JSON_Convert = $JSON_Data | ConvertFrom-Json | Select-Object -Property * -ExcludeProperty id, createdDateTime, lastModifiedDateTime, scheduledActionsForRule@odata.context @@ -481,9 +456,8 @@ Foreach-object { $JSON_Output = $JSON_Convert | ConvertTo-Json -Depth 10 - # Adding Scheduled Actions Rule to JSON - #$scheduledActionsForRule = '"scheduledActionsForRule":[{"ruleName":"PasswordRequired","scheduledActionConfigurations":[{"actionType":"block","gracePeriodHours":0,"notificationTemplateId":"","notificationMessageCCList":[]}]}]' + #$scheduledActionsForRule = '"scheduledActionsForRule":[{"ruleName":"PasswordRequired","scheduledActionConfigurations":[{"actionType":"block","gracePeriodHours":0,"notificationTemplateId":"","notificationMessageCCList":[]}]}]' #$JSON_Output = $JSON_Output.trimend("}") @@ -491,12 +465,12 @@ Foreach-object { # Joining the JSON together #$JSON_Output = $JSON_Output + $scheduledActionsForRule + "`r`n" + "}" - - write-host - write-host "Device Configuration Policy '$DisplayName' Found..." -ForegroundColor Yellow - write-host + + Write-Host + Write-Host "Device Configuration Policy '$DisplayName' Found..." -ForegroundColor Yellow + Write-Host $JSON_Output - write-host + Write-Host Write-Host "Adding Device Configuration Policy '$DisplayName'" -ForegroundColor Yellow Add-DeviceCompliancePolicy -JSON $JSON_Output @@ -511,16 +485,14 @@ Foreach-object { $ComplianceAssignments = @() - foreach ($AADGroup in $AADGroups ) - - { - Write-Host "AAD Group Name:" $AADGroup.groupId -ForegroundColor Yellow - Write-Host "Assignment Type:" $AADGroup."@OData.type" -ForegroundColor Yellow + foreach ($AADGroup in $AADGroups ) { + Write-Host 'AAD Group Name:' $AADGroup.groupId -ForegroundColor Yellow + Write-Host 'Assignment Type:' $AADGroup.'@OData.type' -ForegroundColor Yellow $TargetGroupId = (Get-AADGroup -GroupName $AADGroup.groupid) $TargetGroupId = $TargetGroupId.id - Write-Host "Included Group ID:" $TargetGroupID -ForegroundColor Yellow + Write-Host 'Included Group ID:' $TargetGroupID -ForegroundColor Yellow - $Assignment = $AADGroup."@OData.type" + $Assignment = $AADGroup.'@OData.type' $GroupAdd = @" { "target": { @@ -530,17 +502,16 @@ Foreach-object { }, "@ - + $ComplianceAssignments += $GroupAdd } - + Add-DeviceCompliancePolicyAssignment -ComplianceAssignments $ComplianceAssignments -CompliancePolicyId $CompliancePolicyId - - } - else - { - write-host "Device Compliance Policy:" $JSON_Convert.displayName "has already been created" -ForegroundColor Yellow } -} + else { + Write-Host 'Device Compliance Policy:' $JSON_Convert.displayName 'has already been created' -ForegroundColor Yellow + } + +} diff --git a/PAW/Import-PAW-DeviceConfiguration.ps1 b/PAW/Import-PAW-DeviceConfiguration.ps1 index cce22b4..76f1fdb 100644 --- a/PAW/Import-PAW-DeviceConfiguration.ps1 +++ b/PAW/Import-PAW-DeviceConfiguration.ps1 @@ -7,8 +7,7 @@ See LICENSE in the project root for license information. #> $ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path -$ImportPath = $ScriptDir + "\JSON\DeviceConfiguration" - +$ImportPath = $ScriptDir + '\JSON\DeviceConfiguration' #################################################### @@ -26,7 +25,7 @@ Authenticates you with the Graph API interface NAME: Test-MgAuth #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -34,21 +33,21 @@ NAME: Test-MgAuth $User ) - $userUpn = New-Object "System.Net.Mail.MailAddress" -ArgumentList $User + $userUpn = New-Object 'System.Net.Mail.MailAddress' -ArgumentList $User $tenant = $userUpn.Host - Write-Host "Checking for Microsoft Graph module..." + Write-Host 'Checking for Microsoft Graph module...' - $MgModule = Get-Module -Name "Microsoft.Graph" -ListAvailable + $MgModule = Get-Module -Name 'Microsoft.Graph' -ListAvailable if ($null -eq $MgModule) { - write-host - write-host "Microsoft Graph Powershell module not installed..." -f Red - write-host "Install by running 'Install-Module Microsoft.Graph' or 'Install-Module Microsoft.Graph' from an elevated PowerShell prompt" -f Yellow - write-host "Script can't continue..." -f Red - write-host - + Write-Host + Write-Host 'Microsoft Graph Powershell module not installed...' -f Red + Write-Host "Install by running 'Install-Module Microsoft.Graph' or 'Install-Module Microsoft.Graph' from an elevated PowerShell prompt" -f Yellow + Write-Host "Script can't continue..." -f Red + Write-Host + } $scopes = @() @@ -56,21 +55,20 @@ NAME: Test-MgAuth ######################################### # Directory related scopes # ######################################### - $scopes += @("Device.Read.All", - "User.Read.All", - "GroupMember.ReadWrite.All", - "Group.ReadWrite.All", - "Directory.ReadWrite.All") + $scopes += @('Device.Read.All', + 'User.Read.All', + 'GroupMember.ReadWrite.All', + 'Group.ReadWrite.All', + 'Directory.ReadWrite.All') ######################################### # Device Management scopes # ######################################### - $scopes += @("DeviceManagementConfiguration.ReadWrite.All", - "DeviceManagementServiceConfig.ReadWrite.All", - "DeviceManagementRBAC.ReadWrite.All", - "DeviceManagementManagedDevices.ReadWrite.All", - "DeviceManagementApps.ReadWrite.All") - + $scopes += @('DeviceManagementConfiguration.ReadWrite.All', + 'DeviceManagementServiceConfig.ReadWrite.All', + 'DeviceManagementRBAC.ReadWrite.All', + 'DeviceManagementManagedDevices.ReadWrite.All', + 'DeviceManagementApps.ReadWrite.All') #$clientId = "d1ddf0e4-d672-4dae-b554-9d5bdfd93547" #$redirectUri = "urn:ietf:wg:oauth:2.0:oob" @@ -84,11 +82,11 @@ NAME: Test-MgAuth $ctx = Get-MgContext $org = Get-MgOrganization - $domains = $org.VerifiedDomains | select-object -ExpandProperty Name + $domains = $org.VerifiedDomains | Select-Object -ExpandProperty Name if ($ctx.Account.ToLower() -ne $userUpn.Address.ToLower() -or ($ctx.TenantId -ne $org.Id) -or $domains -notcontains $tenant) { - write-host "Unable to verify tenant or account" -f Red + Write-Host 'Unable to verify tenant or account' -f Red Disconnect-MgGraph - throw "Unable to continue due to validation" + throw 'Unable to continue due to validation' } # $authHeader = @{ @@ -100,13 +98,12 @@ NAME: Test-MgAuth # return $authHeader } catch { - write-host $_.Exception.Message -f Red - write-host $_.Exception.ItemName -f Red - write-host + Write-Host $_.Exception.Message -f Red + Write-Host $_.Exception.ItemName -f Red + Write-Host break } - } #################################################### @@ -125,42 +122,40 @@ Adds a device configuration policy in Intune NAME: Add-DeviceConfigurationPolicy #> - [cmdletbinding()] + [CmdletBinding()] param ( $JSON ) - $graphApiVersion = "Beta" - $DCP_resource = "deviceManagement/deviceConfigurations" + $graphApiVersion = 'Beta' + $DCP_resource = 'deviceManagement/deviceConfigurations' Write-Verbose "Resource: $DCP_resource" try { - if ($JSON -eq "" -or $null -eq $JSON) { - - write-host "No JSON specified, please specify valid JSON for the Policy..." -f Red + if ([string]::IsNullOrWhiteSpace($JSON)) { + Write-Host 'No JSON specified, please specify valid JSON for the Policy...' -f Red } else { - Test-JSON -JSON $JSON + Test-Json -Json $JSON $uri = "https://graph.microsoft.com/$graphApiVersion/$($DCP_resource)" - Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType "application/json" + Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType 'application/json' } } catch { $ex = $_.Exception - Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break } @@ -183,7 +178,7 @@ Adds a device configuration policy assignment in Intune NAME: Add-DeviceConfigurationPolicyAssignment #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -192,32 +187,31 @@ NAME: Add-DeviceConfigurationPolicyAssignment $Assignment ) - $graphApiVersion = "Beta" + $graphApiVersion = 'Beta' $Resource = "deviceManagement/deviceConfigurations/$ConfigurationPolicyId/assignments" - + try { if (!$ConfigurationPolicyId) { - write-host "No Configuration Policy Id specified, specify a valid Configuration Policy Id" -f Red + Write-Host 'No Configuration Policy Id specified, specify a valid Configuration Policy Id' -f Red break } if (!$TargetGroupId) { - write-host "No Target Group Id specified, specify a valid Target Group Id" -f Red + Write-Host 'No Target Group Id specified, specify a valid Target Group Id' -f Red break - + } if (!$Assignment) { - write-host "No Assignment Type specified, specify a valid Assignment Type" -f Red + Write-Host 'No Assignment Type specified, specify a valid Assignment Type' -f Red break } - $ConfPolAssign = "$ConfigurationPolicyId" + "_" + "$TargetGroupId" - + $ConfPolAssign = "$ConfigurationPolicyId" + '_' + "$TargetGroupId" $JSON = @" @@ -230,26 +224,24 @@ NAME: Add-DeviceConfigurationPolicyAssignment "@ $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)" - Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType "application/json" + Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType 'application/json' } - + catch { $ex = $_.Exception - + Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break } - } #################################################### - Function Get-DeviceConfigurationPolicy() { <# @@ -264,15 +256,15 @@ Returns any device configuration policies configured in Intune NAME: Get-DeviceConfigurationPolicy #> - [cmdletbinding()] + [CmdletBinding()] param ( $name ) - $graphApiVersion = "Beta" - $DCP_resource = "deviceManagement/deviceConfigurations" + $graphApiVersion = 'Beta' + $DCP_resource = 'deviceManagement/deviceConfigurations' try { @@ -289,17 +281,15 @@ NAME: Get-DeviceConfigurationPolicy (Invoke-MgGraphRequest -Uri $uri -Method Get).Value } - } catch { $ex = $_.Exception - Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break } @@ -322,7 +312,7 @@ Returns all users registered with Azure AD NAME: Get-AADGroup #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -332,11 +322,11 @@ NAME: Get-AADGroup ) # Defining Variables - $graphApiVersion = "v1.0" - $Group_resource = "groups" + $graphApiVersion = 'v1.0' + $Group_resource = 'groups' # pseudo-group identifiers for all users and all devices - [string]$AllUsers = "acacacac-9df4-4c7d-9d50-4ef0226f57a9" - [string]$AllDevices = "adadadad-808e-44e2-905a-0b7873a8a531" + [string]$AllUsers = 'acacacac-9df4-4c7d-9d50-4ef0226f57a9' + [string]$AllDevices = 'adadadad-808e-44e2-905a-0b7873a8a531' try { @@ -344,14 +334,14 @@ NAME: Get-AADGroup $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)?`$filter=id eq '$id'" switch ( $id ) { - $AllUsers { $grp = [PSCustomObject]@{ displayName = "All users" }; $grp } - $AllDevices { $grp = [PSCustomObject]@{ displayName = "All devices" }; $grp } + $AllUsers { $grp = [PSCustomObject]@{ displayName = 'All users' }; $grp } + $AllDevices { $grp = [PSCustomObject]@{ displayName = 'All devices' }; $grp } default { (Invoke-MgGraphRequest -Uri $uri -Method Get).Value } } - + } - elseif ($GroupName -eq "" -or $null -eq $GroupName) { + elseif ([string]::IsNullOrWhiteSpace($GroupName)) { $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)" (Invoke-MgGraphRequest -Uri $uri -Method Get).Value @@ -377,27 +367,23 @@ NAME: Get-AADGroup $GID = $Group.id $Group.displayName - write-host + Write-Host $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)/$GID/Members" (Invoke-MgGraphRequest -Uri $uri -Method Get).Value } - } - } - } catch { $ex = $_.Exception - Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break } @@ -420,16 +406,13 @@ NAME: Test-AuthHeader #> param ( - $JSON - ) try { $TestJSON = ConvertFrom-Json $JSON -ErrorAction Stop $validJson = $true - } catch { @@ -440,25 +423,22 @@ NAME: Test-AuthHeader } if (!$validJson) { - + Write-Host "Provided JSON isn't in valid JSON format" -f Red break - } - } #################################################### #region Authentication -write-host +Write-Host -if ($null -eq $User -or $User -eq "") { +if ([string]::IsNullOrWhiteSpace($User)) { - $User = Read-Host -Prompt "Please specify your user principal name for Azure Authentication" + $User = Read-Host -Prompt 'Please specify your user principal name for Azure Authentication' Write-Host - } Test-MgAuth -User $User @@ -495,8 +475,8 @@ if (!(Test-Path "$ImportPath")) { #################################################### -Get-ChildItem $ImportPath -filter *.json | -Foreach-object { +Get-ChildItem $ImportPath -Filter *.json | +ForEach-Object { $JSON_Data = Get-Content $_.FullName @@ -507,15 +487,14 @@ Foreach-object { $DuplicateDCP = Get-DeviceConfigurationPolicy -Name $JSON_Convert.displayName - If ($DuplicateDCP -eq $null) { $JSON_Output = $JSON_Convert | ConvertTo-Json -Depth 5 - - write-host - write-host "Device Configuration Policy '$DisplayName' Found..." -ForegroundColor Yellow - write-host + + Write-Host + Write-Host "Device Configuration Policy '$DisplayName' Found..." -ForegroundColor Yellow + Write-Host $JSON_Output - write-host + Write-Host Write-Host "Adding Device Configuration Policy '$DisplayName'" -ForegroundColor Yellow Add-DeviceConfigurationPolicy -JSON $JSON_Output @@ -524,33 +503,32 @@ Foreach-object { $DeviceConfigID = $DeviceConfigs.id - Write-Host "Device ConfigID '$DeviceConfigID'" -ForegroundColor Yellow + Write-Host "Device ConfigID '$DeviceConfigID'" -ForegroundColor Yellow Write-Host $AADGroups = $JSON_Convert.assignments.target - foreach ($AADGroup in $AADGroups ) - { - Write-Host "AAD Group Name:" $AADGroup.groupId -ForegroundColor Yellow - Write-Host "Assignment Type:" $AADGroup."@OData.type" -ForegroundColor Yellow - + foreach ($AADGroup in $AADGroups ) { + Write-Host 'AAD Group Name:' $AADGroup.groupId -ForegroundColor Yellow + Write-Host 'Assignment Type:' $AADGroup.'@OData.type' -ForegroundColor Yellow + $TargetGroupId = (Get-AADGroup -GroupName $AADGroup.groupid) - Write-Host "Included Group ID:" $TargetGroupID.Id -ForegroundColor Yellow - Add-DeviceConfigurationPolicyAssignment -ConfigurationPolicyId $DeviceConfigID -TargetGroupId $TargetGroupId.id -Assignment $AADGroup."@OData.type" + Write-Host 'Included Group ID:' $TargetGroupID.Id -ForegroundColor Yellow + Add-DeviceConfigurationPolicyAssignment -ConfigurationPolicyId $DeviceConfigID -TargetGroupId $TargetGroupId.id -Assignment $AADGroup.'@OData.type' } - + # Create exclude Group - + <#$ShortName = $JSON_Convert.displayName -replace "PAW-Global-2009-Intune-Configuration-", '' - $ExcludeGroup = "PAW-"+$ShortName+"-Exclude-Device" + $ExcludeGroup = "PAW-"+$ShortName+"-Exclude-Device" If (Get-AzureADGroup -SearchString $ExcludeGroup) { Write-Host Write-Host "AAD group" $ExcludeGroup "already exists!" -f Yellow Write-Host } Else { - + $MailNickName = $ShortName+"-G" - + try { $ExcludeTargetGroup = New-AzureADGroup -DisplayName $ExcludeGroup -Description $ExcludeGroup"-Group" -MailEnabled $false -SecurityEnabled $true -MailNickName $MailNickName @@ -563,15 +541,15 @@ Foreach-object { Write-Host } - } - + } + Write-Host "Excluded Group ID" $ExcludeTargetGroup.objectid Add-DeviceConfigurationPolicyAssignment -ConfigurationPolicyId $DeviceConfigID -TargetGroupId $ExcludeTargetGroup.objectid -Assignment "exclusionGroupAssignmentTarget" #> } - + else { - write-host "Device Configuration Profile:" $JSON_Convert.displayName "has already been created" -ForegroundColor Yellow + Write-Host 'Device Configuration Profile:' $JSON_Convert.displayName 'has already been created' -ForegroundColor Yellow } -} \ No newline at end of file +} diff --git a/PAW/Import-PAW-DeviceConfigurationADMX.ps1 b/PAW/Import-PAW-DeviceConfigurationADMX.ps1 index 681e4fa..caef519 100644 --- a/PAW/Import-PAW-DeviceConfigurationADMX.ps1 +++ b/PAW/Import-PAW-DeviceConfigurationADMX.ps1 @@ -10,13 +10,13 @@ param ( #Change Conditional Access State, default is disabled #Options: enabled, disabled, enabledForReportingButNotEnforced - [String]$AADGroup = "Privileged Workstations" - + [String]$AADGroup = 'Privileged Workstations' + ) #$AADGroup = "PAW-Global-Devices" $ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path -$ImportPath = $ScriptDir + "\JSON\DeviceConfigurationADMX" +$ImportPath = $ScriptDir + '\JSON\DeviceConfigurationADMX' function Test-MgAuth { @@ -32,7 +32,7 @@ Authenticates you with the Graph API interface NAME: Test-MgAuth #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -40,21 +40,20 @@ NAME: Test-MgAuth $User ) - $userUpn = New-Object "System.Net.Mail.MailAddress" -ArgumentList $User + $userUpn = New-Object 'System.Net.Mail.MailAddress' -ArgumentList $User $tenant = $userUpn.Host - Write-Host "Checking for Microsoft Graph module..." + Write-Host 'Checking for Microsoft Graph module...' - $MgModule = Get-Module -Name "Microsoft.Graph" -ListAvailable + $MgModule = Get-Module -Name 'Microsoft.Graph' -ListAvailable if ($null -eq $MgModule) { - write-host - write-host "Microsoft Graph Powershell module not installed..." -f Red - write-host "Install by running 'Install-Module Microsoft.Graph' or 'Install-Module Microsoft.Graph' from an elevated PowerShell prompt" -f Yellow - write-host "Script can't continue..." -f Red - write-host - + Write-Host + Write-Host 'Microsoft Graph Powershell module not installed...' -f Red + Write-Host "Install by running 'Install-Module Microsoft.Graph' or 'Install-Module Microsoft.Graph' from an elevated PowerShell prompt" -f Yellow + Write-Host "Script can't continue..." -f Red + Write-Host } $scopes = @() @@ -62,20 +61,20 @@ NAME: Test-MgAuth ######################################### # Directory related scopes # ######################################### - $scopes += @("Device.Read.All", - "User.Read.All", - "GroupMember.ReadWrite.All", - "Group.ReadWrite.All", - "Directory.ReadWrite.All") + $scopes += @('Device.Read.All', + 'User.Read.All', + 'GroupMember.ReadWrite.All', + 'Group.ReadWrite.All', + 'Directory.ReadWrite.All') ######################################### # Device Management scopes # ######################################### - $scopes += @("DeviceManagementConfiguration.ReadWrite.All", - "DeviceManagementServiceConfig.ReadWrite.All", - "DeviceManagementRBAC.ReadWrite.All", - "DeviceManagementManagedDevices.ReadWrite.All", - "DeviceManagementApps.ReadWrite.All") + $scopes += @('DeviceManagementConfiguration.ReadWrite.All', + 'DeviceManagementServiceConfig.ReadWrite.All', + 'DeviceManagementRBAC.ReadWrite.All', + 'DeviceManagementManagedDevices.ReadWrite.All', + 'DeviceManagementApps.ReadWrite.All') #$clientId = "d1ddf0e4-d672-4dae-b554-9d5bdfd93547" @@ -90,11 +89,11 @@ NAME: Test-MgAuth $ctx = Get-MgContext $org = Get-MgOrganization - $domains = $org.VerifiedDomains | select-object -ExpandProperty Name + $domains = $org.VerifiedDomains | Select-Object -ExpandProperty Name if ($ctx.Account.ToLower() -ne $userUpn.Address.ToLower() -or ($ctx.TenantId -ne $org.Id) -or $domains -notcontains $tenant) { - write-host "Unable to verify tenant or account" -f Red + Write-Host 'Unable to verify tenant or account' -f Red Disconnect-MgGraph - throw "Unable to continue due to validation" + throw 'Unable to continue due to validation' } # $authHeader = @{ @@ -106,19 +105,18 @@ NAME: Test-MgAuth # return $authHeader } catch { - write-host $_.Exception.Message -f Red - write-host $_.Exception.ItemName -f Red - write-host + Write-Host $_.Exception.Message -f Red + Write-Host $_.Exception.ItemName -f Red + Write-Host break } - } - + #################################################### - + Function Create-GroupPolicyConfigurations() { - + <# .SYNOPSIS This function is used to add an device configuration policy using the Graph API REST interface @@ -130,49 +128,45 @@ Adds a device configuration policy in Intune .NOTES NAME: Add-DeviceConfigurationPolicy #> - - [cmdletbinding()] + + [CmdletBinding()] param ( $DisplayName ) - + $jsonCode = @" { "description":"", "displayName":"$($DisplayName)" } "@ - - $graphApiVersion = "Beta" - $DCP_resource = "deviceManagement/groupPolicyConfigurations" + + $graphApiVersion = 'Beta' + $DCP_resource = 'deviceManagement/groupPolicyConfigurations' Write-Verbose "Resource: $DCP_resource" - + try { - + $uri = "https://graph.microsoft.com/$graphApiVersion/$($DCP_resource)" - $responseBody = Invoke-MgGraphRequest -Uri $uri -Method Post -Body $jsonCode -ContentType "application/json" - - + $responseBody = Invoke-MgGraphRequest -Uri $uri -Method Post -Body $jsonCode -ContentType 'application/json' } - + catch { - + $ex = $_.Exception - Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break - + } $responseBody.id } - - + Function Create-GroupPolicyConfigurationsDefinitionValues() { - + <# .SYNOPSIS This function is used to get device configuration policies from the Graph API REST interface @@ -184,55 +178,47 @@ Function Create-GroupPolicyConfigurationsDefinitionValues() { .NOTES NAME: Get-GroupPolicyConfigurations #> - - [cmdletbinding()] + + [CmdletBinding()] Param ( - + [string]$GroupPolicyConfigurationID, $JSON - ) - - $graphApiVersion = "Beta" - + + $graphApiVersion = 'Beta' + $DCP_resource = "deviceManagement/groupPolicyConfigurations/$($GroupPolicyConfigurationID)/definitionValues" - write-host $DCP_resource + Write-Host $DCP_resource try { - if ($JSON -eq "" -or $null -eq $JSON) { - - write-host "No JSON specified, please specify valid JSON for the Device Configuration Policy..." -f Red - + if ([string]::IsNullOrWhiteSpace($JSON)) { + + Write-Host 'No JSON specified, please specify valid JSON for the Device Configuration Policy...' -f Red } - + else { - - Test-JSON -JSON $JSON - + + Test-Json -Json $JSON + $uri = "https://graph.microsoft.com/$graphApiVersion/$($DCP_resource)" - Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType "application/json" + Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType 'application/json' } - } - + catch { - $ex = $_.Exception - Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break - } - } - - + #################################################### Function Get-GroupPolicyConfigurations() { - + <# .SYNOPSIS This function is used to get device configuration policies from the Graph API REST interface @@ -244,37 +230,35 @@ Returns any device configuration policies configured in Intune .NOTES NAME: Get-GroupPolicyConfigurations #> - - [cmdletbinding()] + + [CmdletBinding()] param ( $name ) - - $graphApiVersion = "Beta" - $DCP_resource = "deviceManagement/groupPolicyConfigurations" - + $graphApiVersion = 'Beta' + $DCP_resource = 'deviceManagement/groupPolicyConfigurations' + try { - + $uri = "https://graph.microsoft.com/$graphApiVersion/$($DCP_resource)" (Invoke-MgGraphRequest -Uri $uri -Method Get).Value | Where-Object { ($_.'displayName') -eq ("$Name") } - + } - + catch { - + $ex = $_.Exception - + Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break - + } - } #################################################### @@ -293,7 +277,7 @@ Adds a device configuration policy assignment in Intune NAME: Add-DeviceConfigurationPolicyAssignment #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -302,33 +286,32 @@ NAME: Add-DeviceConfigurationPolicyAssignment $Assignment ) - $graphApiVersion = "Beta" + $graphApiVersion = 'Beta' $Resource = "deviceManagement/groupPolicyConfigurations/$ConfigurationPolicyId/assignments" - + try { if (!$ConfigurationPolicyId) { - write-host "No Configuration Policy Id specified, specify a valid Configuration Policy Id" -f Red + Write-Host 'No Configuration Policy Id specified, specify a valid Configuration Policy Id' -f Red break } if (!$TargetGroupId) { - write-host "No Target Group Id specified, specify a valid Target Group Id" -f Red + Write-Host 'No Target Group Id specified, specify a valid Target Group Id' -f Red break - + } if (!$Assignment) { - write-host "No Assignment Type specified, specify a valid Assignment Type" -f Red + Write-Host 'No Assignment Type specified, specify a valid Assignment Type' -f Red break } # $ConfPolAssign = "$ConfigurationPolicyId" + "_" + "$TargetGroupId" - $JSON = @" { @@ -340,22 +323,21 @@ NAME: Add-DeviceConfigurationPolicyAssignment "@ $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)" - Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType "application/json" + Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType 'application/json' } - + catch { $ex = $_.Exception - + Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break } - } #################################################### @@ -374,7 +356,7 @@ Returns all users registered with Azure AD NAME: Get-AADGroup #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -384,11 +366,11 @@ NAME: Get-AADGroup ) # Defining Variables - $graphApiVersion = "v1.0" - $Group_resource = "groups" + $graphApiVersion = 'v1.0' + $Group_resource = 'groups' # pseudo-group identifiers for all users and all devices - [string]$AllUsers = "acacacac-9df4-4c7d-9d50-4ef0226f57a9" - [string]$AllDevices = "adadadad-808e-44e2-905a-0b7873a8a531" + [string]$AllUsers = 'acacacac-9df4-4c7d-9d50-4ef0226f57a9' + [string]$AllDevices = 'adadadad-808e-44e2-905a-0b7873a8a531' try { @@ -396,14 +378,14 @@ NAME: Get-AADGroup $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)?`$filter=id eq '$id'" switch ( $id ) { - $AllUsers { $grp = [PSCustomObject]@{ displayName = "All users" }; $grp } - $AllDevices { $grp = [PSCustomObject]@{ displayName = "All devices" }; $grp } + $AllUsers { $grp = [PSCustomObject]@{ displayName = 'All users' }; $grp } + $AllDevices { $grp = [PSCustomObject]@{ displayName = 'All devices' }; $grp } default { (Invoke-MgGraphRequest -Uri $uri -Method Get).Value } } - + } - elseif ($GroupName -eq "" -or $null -eq $GroupName) { + elseif ([string]::IsNullOrWhiteSpace($GroupName)) { $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)" (Invoke-MgGraphRequest -Uri $uri -Method Get).Value @@ -429,37 +411,33 @@ NAME: Get-AADGroup $GID = $Group.id $Group.displayName - write-host + Write-Host $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)/$GID/Members" (Invoke-MgGraphRequest -Uri $uri -Method Get).Value } - } - } - } catch { $ex = $_.Exception - + Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break } - } #################################################### Function Test-JSON() { - + <# .SYNOPSIS This function is used to test if the JSON passed to a REST Post request is valid @@ -471,57 +449,50 @@ Test if the JSON is valid before calling the Graph REST interface .NOTES NAME: Test-AuthHeader #> - + param ( - $JSON - ) - + try { - - $TestJSON = ConvertFrom-Json $JSON -ErrorAction Stop + $null = ConvertFrom-Json $JSON -ErrorAction Stop $validJson = $true - } - + catch { - + $validJson = $false $_.Exception - + } - + if (!$validJson) { - + Write-Host "Provided JSON isn't in valid JSON format" -f Red break - + } - } - + #################################################### - + #region Authentication - -write-host - + +Write-Host + # Defining User Principal Name if not present -if ($null -eq $User -or $User -eq "") { - - $User = Read-Host -Prompt "Please specify your user principal name for Azure Authentication" +if ([string]::IsNullOrWhiteSpace($User)) { + + $User = Read-Host -Prompt 'Please specify your user principal name for Azure Authentication' Write-Host } - + # Getting the authorization token Test-MgAuth -User $User - - + #endregion - + #################################################### - # Replacing quotes for Test-Path $ImportPath = $ImportPath.replace('"', '') @@ -532,15 +503,14 @@ if (!(Test-Path "$ImportPath")) { Write-Host "Script can't continue..." -ForegroundColor Red Write-Host break - + } #################################################### - $TargetGroupId = (Get-AADGroup | Where-Object { $_.displayName -eq $AADGroup }).id -if ($null -eq $TargetGroupId -or $TargetGroupId -eq "") { +if ([string]::IsNullOrWhiteSpace($TargetGroupId)) { Write-Host "AAD Group - '$AADGroup' doesn't exist, please specify a valid AAD Group..." -ForegroundColor Red Write-Host @@ -551,44 +521,40 @@ if ($null -eq $TargetGroupId -or $TargetGroupId -eq "") { #################################################### - -Get-ChildItem $ImportPath -filter *.json | +Get-ChildItem $ImportPath -Filter *.json | ForEach-Object { $Policy_Name = $_.Name $Policy_Name = $Policy_Name.Substring(0, $Policy_Name.Length - 5) - + $DuplicateDCP = Get-GroupPolicyConfigurations -Name $Policy_Name - If ($DuplicateDCP -eq $null) - { + If ($DuplicateDCP -eq $null) { $GroupPolicyConfigurationID = Create-GroupPolicyConfigurations -DisplayName $Policy_Name $JSON_Data = Get-Content $_.FullName $JSON_Convert = $JSON_Data | ConvertFrom-Json $JSON_Convert | ForEach-Object { $_ - - $JSON_Output = Convertto-Json -Depth 5 $_ + + $JSON_Output = ConvertTo-Json -Depth 5 $_ Write-Host $JSON_Output - Create-GroupPolicyConfigurationsDefinitionValues -JSON $JSON_Output -GroupPolicyConfigurationID $GroupPolicyConfigurationID + Create-GroupPolicyConfigurationsDefinitionValues -JSON $JSON_Output -GroupPolicyConfigurationID $GroupPolicyConfigurationID } - Write-Host "####################################################################################################" -ForegroundColor Green - Write-Host "Policy: " $Policy_Name "created" -ForegroundColor Green - Write-Host "####################################################################################################" -ForegroundColor Green + Write-Host '####################################################################################################' -ForegroundColor Green + Write-Host 'Policy: ' $Policy_Name 'created' -ForegroundColor Green + Write-Host '####################################################################################################' -ForegroundColor Green $DeviceConfigs = Get-GroupPolicyConfigurations -name $Policy_Name $DeviceConfigID = $DeviceConfigs.id - - Add-GroupPolicyConfigurationPolicyAssignment -ConfigurationPolicyId $DeviceConfigID -TargetGroupId $TargetGroupId -Assignment "groupAssignmentTarget" + + Add-GroupPolicyConfigurationPolicyAssignment -ConfigurationPolicyId $DeviceConfigID -TargetGroupId $TargetGroupId -Assignment 'groupAssignmentTarget' } - else - { - write-host "Device Configuration ADMX Profile:" $Policy_Name "has already been created" -ForegroundColor Yellow + else { + Write-Host 'Device Configuration ADMX Profile:' $Policy_Name 'has already been created' -ForegroundColor Yellow } } - diff --git a/PAW/MasterScript PAW.ps1 b/PAW/MasterScript PAW.ps1 index a6c8683..6eab95c 100644 --- a/PAW/MasterScript PAW.ps1 +++ b/PAW/MasterScript PAW.ps1 @@ -23,7 +23,7 @@ Authenticates you with the Graph API interface NAME: Test-MgAuth #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -31,21 +31,20 @@ NAME: Test-MgAuth $User ) - $userUpn = New-Object "System.Net.Mail.MailAddress" -ArgumentList $User + $userUpn = New-Object 'System.Net.Mail.MailAddress' -ArgumentList $User $tenant = $userUpn.Host - Write-Host "Checking for Microsoft Graph module..." + Write-Host 'Checking for Microsoft Graph module...' - $MgModule = Get-Module -Name "Microsoft.Graph" -ListAvailable + $MgModule = Get-Module -Name 'Microsoft.Graph' -ListAvailable if ($null -eq $MgModule) { - write-host - write-host "Microsoft Graph Powershell module not installed..." -f Red - write-host "Install by running 'Install-Module Microsoft.Graph' or 'Install-Module Microsoft.Graph' from an elevated PowerShell prompt" -f Yellow - write-host "Script can't continue..." -f Red - write-host - + Write-Host + Write-Host 'Microsoft Graph Powershell module not installed...' -f Red + Write-Host "Install by running 'Install-Module Microsoft.Graph' or 'Install-Module Microsoft.Graph' from an elevated PowerShell prompt" -f Yellow + Write-Host "Script can't continue..." -f Red + Write-Host } $scopes = @() @@ -53,21 +52,20 @@ NAME: Test-MgAuth ######################################### # Directory related scopes # ######################################### - $scopes += @("Device.Read.All", - "User.Read.All", - "GroupMember.ReadWrite.All", - "Group.ReadWrite.All", - "Directory.ReadWrite.All") + $scopes += @('Device.Read.All', + 'User.Read.All', + 'GroupMember.ReadWrite.All', + 'Group.ReadWrite.All', + 'Directory.ReadWrite.All') ######################################### # Device Management scopes # ######################################### - $scopes += @("DeviceManagementConfiguration.ReadWrite.All", - "DeviceManagementServiceConfig.ReadWrite.All", - "DeviceManagementRBAC.ReadWrite.All", - "DeviceManagementManagedDevices.ReadWrite.All", - "DeviceManagementApps.ReadWrite.All") - + $scopes += @('DeviceManagementConfiguration.ReadWrite.All', + 'DeviceManagementServiceConfig.ReadWrite.All', + 'DeviceManagementRBAC.ReadWrite.All', + 'DeviceManagementManagedDevices.ReadWrite.All', + 'DeviceManagementApps.ReadWrite.All') #$clientId = "d1ddf0e4-d672-4dae-b554-9d5bdfd93547" #$redirectUri = "urn:ietf:wg:oauth:2.0:oob" @@ -81,11 +79,11 @@ NAME: Test-MgAuth $ctx = Get-MgContext $org = Get-MgOrganization - $domains = $org.VerifiedDomains | select-object -ExpandProperty Name + $domains = $org.VerifiedDomains | Select-Object -ExpandProperty Name if ($ctx.Account.ToLower() -ne $userUpn.Address.ToLower() -or ($ctx.TenantId -ne $org.Id) -or $domains -notcontains $tenant) { - write-host "Unable to verify tenant or account" -f Red + Write-Host 'Unable to verify tenant or account' -f Red Disconnect-MgGraph - throw "Unable to continue due to validation" + throw 'Unable to continue due to validation' } # $authHeader = @{ @@ -97,30 +95,27 @@ NAME: Test-MgAuth # return $authHeader } catch { - write-host $_.Exception.Message -f Red - write-host $_.Exception.ItemName -f Red - write-host + Write-Host $_.Exception.Message -f Red + Write-Host $_.Exception.ItemName -f Red + Write-Host break - } - } - + +#################################################### + +$User = Read-Host -Prompt 'Please specify your user principal name for Microsoft Authentication' + + +Test-MgAuth -user $user + #################################################### - - $User = Read-Host -Prompt "Please specify your user principal name for Microsoft Authentication" - - Test-MgAuth -user $user - - #################################################### - - - #write-host "Adding App Registrtion" +#write-host "Adding App Registration" - #. $ScriptDir/AppRegistration_Create.ps1 - - #Start-Sleep -s 5 +#. $ScriptDir/AppRegistration_Create.ps1 + +#Start-Sleep -s 5 #write-host "Adding required AAD Groups" @@ -144,19 +139,19 @@ NAME: Test-MgAuth #Start-Sleep -s 5 -write-host "Adding Device Configuration Profiles" +Write-Host 'Adding Device Configuration Profiles' . $ScriptDir/Import-PAW-DeviceConfiguration.ps1 #Start-Sleep -s 5 -write-host "Adding Device Compliance Policies" +Write-Host 'Adding Device Compliance Policies' . $ScriptDir/Import-PAW-DeviceCompliancePolicies.ps1 Start-Sleep -s 5 -write-host "Adding Update Rings Policy" +Write-Host 'Adding Update Rings Policy' . $ScriptDir/Import-PAW-DeviceConfigurationADMX.ps1 @@ -179,6 +174,3 @@ Start-Sleep -s 5 #. $ScriptDir/DER-Import_PAW.ps1 #Start-Sleep -s 5 - - - diff --git a/PAW/Readme.md b/PAW/Readme.md index 2df6533..4dbe4e9 100644 --- a/PAW/Readme.md +++ b/PAW/Readme.md @@ -1,6 +1,6 @@ # Privileged Profile configuration -The scripts for configuring the Privileged security baseline are located in this folder. +The scripts for configuring the Privileged security baseline are located in this folder. Before the scripts can be run install Azure AD powershell module on your device ```powershell @@ -12,24 +12,22 @@ Set-ExecutionPolicy remotesigned ``` [**MasterScript_PAW.PS1**](MasterScript-PAW.ps1) - This script is used to import the Compliance policies, Configuration profiles used to apply the Privileged Profile settings - + To import the Privileged Profile configuration settings into your tenant Open powershell console - Navigate to PAW folder in Repo + Navigate to PAW folder in Repo ```powershell .\MasterScript-PAW.ps1 ``` - + PAWer **username** and **password** of an account that has Intune Administrator (preferred) or Global Admin privilege Wait for the import process to complete. The MasterScript_PAW.ps1 file calls the following scripts to import the Compliance Policies, Configuration Profiles - - [**Import-PAW-DeviceCompliancePolicies.ps1**](Import-PAW-DeviceCompliancePolicies.ps1) - This scripts imports the three device compliance policies for the Privileged profile. Three policies are used to ensure that Conditional Access does not prevent a user from being able to access resources. Refer to [Windows 10 and later settings to mark devices as compliant or not compliant using Intune](https://docs.microsoft.com/en-us/mem/intune/protect/compliance-policy-create-windows) - + 1. [Privileged Compliance ATP](JSON/DeviceCompliance/PAW-Compliance-ATP.json) policy is used to feed the Threat Intelligence data from Microsoft Defender for Endpoint into the devices compliance state so its signals can be used as part of the Conditional Access evaluation process. 2. [Privileged Compliance Delayed](JSON/DeviceCompliance/PAW-Compliance-Delayed.json) policy applies a more complete set of compliance settings to the device but its application is delayed by 24 hours. this is because the device health attestation that is required to assess policies like BitLocker and Secure Boot is only calculated once a device has rebooted and then might take a number of hours to process whether the device is compliant or not. @@ -73,8 +71,6 @@ The MasterScript_PAW.ps1 file calls the following scripts to import the Complian > [!NOTE] > There are two rules defined for each rule in the Microsoft Defender Firewall configuration. To restrict the inbound and outbound rules to Windows Services, e.g. DNS Client, both the service name, DNSCache, and the executable path, C:\Windows\System32\svchost.exe, need to be defined as separate rule rather than a single rule that is possible using Group Policy. - [**Import-PAW-DeviceConfigurationADMX.ps1**](JSON/DeviceConfigurationADMX/Privileged-Edge%20Version%2085%20-%20Computer.json) this script is used to import the Device Configuration ADMX Template profile that configures Microsoft Edge security settings. 1. [Privileged-Edge Version 85 - Computer](JSON/DeviceConfigurationADMX/Privileged-Edge%20Version%2085%20-%20Computer.json) applies administrative policies that control features in Microsoft Edge version 77 and later, refer to [Microsoft Edge - Policies](https://docs.microsoft.com/en-us/DeployEdge/microsoft-edge-policies) or more details of the settings applied using the profile. - diff --git a/PAW/Scripts/PAW-DeviceConfig.ps1 b/PAW/Scripts/PAW-DeviceConfig.ps1 index 2fbd831..3e4ae1b 100644 --- a/PAW/Scripts/PAW-DeviceConfig.ps1 +++ b/PAW/Scripts/PAW-DeviceConfig.ps1 @@ -19,17 +19,17 @@ Function Start-Log { [Parameter(HelpMessage = 'Deletes existing file if used with the -DeleteExistingFile switch')] [switch]$DeleteExistingFile ) - + Try { If (!(Test-Path $FilePath)) { ## Create the log file New-Item $FilePath -Type File -Force | Out-Null } - + If ($DeleteExistingFile) { Remove-Item $FilePath -Force } - + ## Set the global variable to be used as the FilePath for all subsequent Write-Log ## calls in this session $script:ScriptLogFilePath = $FilePath @@ -47,7 +47,7 @@ Function Start-Log { param ( [Parameter(Mandatory = $true)] [string]$Message, - + [Parameter()] [ValidateSet(1, 2, 3)] [int]$LogLevel = 1, @@ -81,7 +81,7 @@ NAME: Is-VM [CmdletBinding()] Param () - + Begin { Write-Log -Message "$($MyInvocation.InvocationName) function..." } @@ -96,7 +96,7 @@ NAME: Is-VM $True } else { - Write-Log -Message "Virtual string not found" + Write-Log -Message "Virtual string not found" $False } } @@ -123,7 +123,7 @@ NAME: Is-VM } Else { Write-Host "Machine is a physical device" - + #Enable Hibernate Write-Log -Message "Enabling Hibernation" $command = "C:\Windows\System32\PowerCfg.exe" @@ -170,7 +170,7 @@ NAME: Is-VM #Write-Warning "$($env:computername.ToUpper()) : $($_.Exception.message)" #Exit } - + $command = "C:\Windows\System32\PowerCfg.exe" $args = "/Change standby-timeout-ac 60" $workDir = "C:\Windows\System32" @@ -202,7 +202,7 @@ NAME: Is-VM } Catch { Write-Log -Message "Error changing registry: $($_.Exception.message)" - Write-Warning "Error: $($_.Exception.message)" + Write-Warning "Error: $($_.Exception.message)" Exit } Finally { @@ -220,27 +220,22 @@ NAME: Is-VM } Catch { Write-Log -Message "Error changing AppLocker DLL rule registry key: $($_.Exception.message)" - Write-Warning "Error: $($_.Exception.message)" + Write-Warning "Error: $($_.Exception.message)" Exit } Finally { Write-Log -Message "Finished changing AppLocker DLL rule registry key" } #endregion Configure AppLocker DLL rule registry key - + #region Configure additional Defender for Endpoint security recommendations that cannot be set in Configuration Profiles #Handle registry changes - - - Write-Log -Message "Configuring additional Defender for Endpoint security recommendations that cannot be set in Configuration Profiles" - # Require users to elevate when setting a network's location - prevent changing from Public to Private firewall profile - New-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Network Connections" -Name NC_StdDomainUserSetLocation -Value 1 -PropertyType DWORD -Force - Write-Log -Message "Require users to elevate when setting a network's location - prevent changing from Public to Private firewall profile registry update successfully applied" - # Prevent saving of network credentials + + # Prevent saving of network credentials New-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Control\Lsa -Name DisableDomainCreds -Value 1 -PropertyType DWORD -Force Write-Log -Message "Prevent saving of network credentials registry update successfully applied" # Prevent changing proxy config - + #region Disable Network Location Wizard - prevents users from setting network location as Private and therefore increasing the attack surface exposed in Windows Firewall #region Disable Network Location Wizard #Handle registry changes @@ -260,7 +255,7 @@ NAME: Is-VM } Catch { Write-Log -Message "Error changing registry: $($_.Exception.message)" - Write-Warning "Error: $($_.Exception.message)" + Write-Warning "Error: $($_.Exception.message)" Exit } Finally { @@ -310,7 +305,7 @@ NAME: Is-VM } #endregion Remove WindowsMediaPlayer - + #region RegistryChanges - Set W32Time Parameter Type to NTP #Handle registry changes $registryPath = "HKLM:\SYSTEM\CurrentControlSet\Services\W32Time\Parameters" @@ -332,7 +327,7 @@ NAME: Is-VM } Catch { Write-Log -Message "Error changing registry: $($_.Exception.message)" - Write-Warning "Error: $($_.Exception.message)" + Write-Warning "Error: $($_.Exception.message)" Exit } Finally { @@ -361,14 +356,14 @@ NAME: Is-VM } Catch { Write-Log -Message "Error changing registry: $($_.Exception.message)" - Write-Warning "Error: $($_.Exception.message)" + Write-Warning "Error: $($_.Exception.message)" Exit } Finally { Write-Log -Message "Set Auto Time Sync Service to Automatic start" } #endregion RegistryChanges - Set Auto Time Sync Service to Automatic start - + #region Remove Internet Explorer 11 try { diff --git a/README.md b/README.md index 8fd2e27..9e9a62c 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,12 @@ -# Secure Workstation configuration and policy baselines for Microsoft Intune and Windows 10 +# Secure Workstation configuration and policy baselines for Microsoft Intune and Windows 10 - - - -This site is the companion to the Secured Workstation how-to guidance, providing the scripts to deploy the baseline for the Enterprise, Specialized, and Privileged configurations. +This site is the companion to the Secured Workstation how-to guidance, providing the scripts to deploy the baseline for the Enterprise, Specialized, and Privileged configurations. It is highly recommended, that you familiarize yourself with the guidance prior to cloning, or use the files in this repo. Documentation for the solution can be found at - https://aka.ms/securedworkstation - These files are provided as samples, and a starting point to consider when you build your secured solution. -**The scripts has been tested in a EN-US enviroment only, international langugages may require changes to the script for any geo location related errors.** +**The scripts has been tested in a EN-US environment only, international languages may require changes to the script for any geo location related errors.** # Three Security Profiles @@ -24,13 +20,13 @@ These files are provided as samples, and a starting point to consider when you b * assumes that the user has Standard Privileges on the devices * implements Application Execution Control in Audit mode * does not merge local Windows Defender Firewall rules - + [Specialized policy settings and deployment script](SPE/Readme.md) 3. **Privileged** - is the highest level of security designed for roles that could easily cause a major incident and potential material damage to the organization in the hands of an attacker or malicious insider. This typically includes technical roles with administrative permissions on most or all enterprise systems (and sometimes includes a select few business critical roles). The Privileged profile has the highlighted differences from the Specialized Profile * implements Application Execution Control in Enforced mode * blocks all outbound connections apart from defined Windows Defender Firewall rules - + [Privileged policy settings and deployment script](PAW/Readme.md) **Legacy** - The content of this directory reflects V1 of Azure Secure Workstation diff --git a/SECURITY.md b/SECURITY.md index 869fdfe..f0c2dc1 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -14,7 +14,7 @@ Instead, please report them to the Microsoft Security Response Center (MSRC) at If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). -You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). +You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: diff --git a/SPE/Import-SPE-DeviceCompliancePolicies.ps1 b/SPE/Import-SPE-DeviceCompliancePolicies.ps1 index 00ef5fb..4e4550e 100644 --- a/SPE/Import-SPE-DeviceCompliancePolicies.ps1 +++ b/SPE/Import-SPE-DeviceCompliancePolicies.ps1 @@ -7,7 +7,7 @@ See LICENSE in the project root for license information. #> $ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path -$ImportPath = $ScriptDir + "\JSON\DeviceCompliance" +$ImportPath = $ScriptDir + '\JSON\DeviceCompliance' #################################################### @@ -26,7 +26,7 @@ Authenticates you with the Graph API interface NAME: Test-MgAuth #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -34,21 +34,20 @@ NAME: Test-MgAuth $User ) - $userUpn = New-Object "System.Net.Mail.MailAddress" -ArgumentList $User + $userUpn = New-Object 'System.Net.Mail.MailAddress' -ArgumentList $User $tenant = $userUpn.Host - Write-Host "Checking for Microsoft Graph module..." + Write-Host 'Checking for Microsoft Graph module...' - $MgModule = Get-Module -Name "Microsoft.Graph" -ListAvailable + $MgModule = Get-Module -Name 'Microsoft.Graph' -ListAvailable if ($null -eq $MgModule) { - write-host - write-host "Microsoft Graph Powershell module not installed..." -f Red - write-host "Install by running 'Install-Module Microsoft.Graph' or 'Install-Module Microsoft.Graph' from an elevated PowerShell prompt" -f Yellow - write-host "Script can't continue..." -f Red - write-host - + Write-Host + Write-Host 'Microsoft Graph Powershell module not installed...' -f Red + Write-Host "Install by running 'Install-Module Microsoft.Graph' or 'Install-Module Microsoft.Graph' from an elevated PowerShell prompt" -f Yellow + Write-Host "Script can't continue..." -f Red + Write-Host } $scopes = @() @@ -56,21 +55,20 @@ NAME: Test-MgAuth ######################################### # Directory related scopes # ######################################### - $scopes += @("Device.Read.All", - "User.Read.All", - "GroupMember.ReadWrite.All", - "Group.ReadWrite.All", - "Directory.ReadWrite.All") + $scopes += @('Device.Read.All', + 'User.Read.All', + 'GroupMember.ReadWrite.All', + 'Group.ReadWrite.All', + 'Directory.ReadWrite.All') ######################################### # Device Management scopes # ######################################### - $scopes += @("DeviceManagementConfiguration.ReadWrite.All", - "DeviceManagementServiceConfig.ReadWrite.All", - "DeviceManagementRBAC.ReadWrite.All", - "DeviceManagementManagedDevices.ReadWrite.All", - "DeviceManagementApps.ReadWrite.All") - + $scopes += @('DeviceManagementConfiguration.ReadWrite.All', + 'DeviceManagementServiceConfig.ReadWrite.All', + 'DeviceManagementRBAC.ReadWrite.All', + 'DeviceManagementManagedDevices.ReadWrite.All', + 'DeviceManagementApps.ReadWrite.All') #$clientId = "d1ddf0e4-d672-4dae-b554-9d5bdfd93547" #$redirectUri = "urn:ietf:wg:oauth:2.0:oob" @@ -84,11 +82,11 @@ NAME: Test-MgAuth $ctx = Get-MgContext $org = Get-MgOrganization - $domains = $org.VerifiedDomains | select-object -ExpandProperty Name + $domains = $org.VerifiedDomains | Select-Object -ExpandProperty Name if ($ctx.Account.ToLower() -ne $userUpn.Address.ToLower() -or ($ctx.TenantId -ne $org.Id) -or $domains -notcontains $tenant) { - write-host "Unable to verify tenant or account" -f Red + Write-Host 'Unable to verify tenant or account' -f Red Disconnect-MgGraph - throw "Unable to continue due to validation" + throw 'Unable to continue due to validation' } # $authHeader = @{ @@ -100,13 +98,12 @@ NAME: Test-MgAuth # return $authHeader } catch { - write-host $_.Exception.Message -f Red - write-host $_.Exception.ItemName -f Red - write-host + Write-Host $_.Exception.Message -f Red + Write-Host $_.Exception.ItemName -f Red + Write-Host break } - } #################################################### @@ -124,46 +121,45 @@ Function Add-DeviceCompliancePolicy() { .NOTES NAME: Add-DeviceCompliancePolicy #> - - [cmdletbinding()] - + + [CmdletBinding()] + param ( $JSON ) - - $graphApiVersion = "Beta" - $Resource = "deviceManagement/deviceCompliancePolicies" - + + $graphApiVersion = 'Beta' + $Resource = 'deviceManagement/deviceCompliancePolicies' + try { - - if ($JSON -eq "" -or $null -eq $JSON) { - - write-host "No JSON specified, please specify valid JSON for the iOS Policy..." -f Red - + + if ([string]::IsNullOrWhiteSpace($JSON)) { + + Write-Host 'No JSON specified, please specify valid JSON for the iOS Policy...' -f Red + } - + else { - - Test-JSON -JSON $JSON - + + Test-Json -Json $JSON + $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)" - Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType "application/json" + Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType 'application/json' } } catch { $ex = $_.Exception - + Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break } } - -#################################################### +#################################################### Function Get-AADGroup() { @@ -179,7 +175,7 @@ Returns all users registered with Azure AD NAME: Get-AADGroup #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -189,11 +185,11 @@ NAME: Get-AADGroup ) # Defining Variables - $graphApiVersion = "v1.0" - $Group_resource = "groups" + $graphApiVersion = 'v1.0' + $Group_resource = 'groups' # pseudo-group identifiers for all users and all devices - [string]$AllUsers = "acacacac-9df4-4c7d-9d50-4ef0226f57a9" - [string]$AllDevices = "adadadad-808e-44e2-905a-0b7873a8a531" + [string]$AllUsers = 'acacacac-9df4-4c7d-9d50-4ef0226f57a9' + [string]$AllDevices = 'adadadad-808e-44e2-905a-0b7873a8a531' try { @@ -201,14 +197,14 @@ NAME: Get-AADGroup $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)?`$filter=id eq '$id'" switch ( $id ) { - $AllUsers { $grp = [PSCustomObject]@{ displayName = "All users" }; $grp } - $AllDevices { $grp = [PSCustomObject]@{ displayName = "All devices" }; $grp } + $AllUsers { $grp = [PSCustomObject]@{ displayName = 'All users' }; $grp } + $AllDevices { $grp = [PSCustomObject]@{ displayName = 'All devices' }; $grp } default { (Invoke-MgGraphRequest -Uri $uri -Method Get).Value } } - + } - elseif ($GroupName -eq "" -or $null -eq $GroupName) { + elseif ([string]::IsNullOrWhiteSpace($GroupName)) { $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)" (Invoke-MgGraphRequest -Uri $uri -Method Get).Value @@ -234,31 +230,26 @@ NAME: Get-AADGroup $GID = $Group.id $Group.displayName - write-host + Write-Host $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)/$GID/Members" (Invoke-MgGraphRequest -Uri $uri -Method Get).Value } - } - } - } catch { $ex = $_.Exception - Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break } - } #################################################### @@ -279,38 +270,33 @@ Function Get-DeviceCompliancePolicy() { .NOTES NAME: Get-DeviceCompliancePolicy #> - - [cmdletbinding()] - + + [CmdletBinding()] + param ( $Name ) - $graphApiVersion = "Beta" - $Resource = "deviceManagement/deviceCompliancePolicies" - + $graphApiVersion = 'Beta' + $Resource = 'deviceManagement/deviceCompliancePolicies' + try { - + $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)" - (Invoke-MgGraphRequest -Uri $uri -Method Get).Value | Where-Object { ($_.'@odata.type').contains("windows10CompliancePolicy") -and ($_.'displayName').contains($Name) } - + (Invoke-MgGraphRequest -Uri $uri -Method Get).Value | Where-Object { ($_.'@odata.type').contains('windows10CompliancePolicy') -and ($_.'displayName').contains($Name) } } - + catch { - + $ex = $_.Exception - Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break - + } - } - - #################################################### @@ -327,34 +313,32 @@ Function Add-DeviceCompliancePolicyAssignment() { .NOTES NAME: Add-DeviceCompliancePolicyAssignment #> - - [cmdletbinding()] - + + [CmdletBinding()] + param ( $CompliancePolicyId, $ComplianceAssignments ) - - $graphApiVersion = "v1.0" + + $graphApiVersion = 'v1.0' $Resource = "deviceManagement/deviceCompliancePolicies/$CompliancePolicyId/assign" - + try { - + if (!$CompliancePolicyId) { - - write-host "No Compliance Policy Id specified, specify a valid Compliance Policy Id" -f Red + + Write-Host 'No Compliance Policy Id specified, specify a valid Compliance Policy Id' -f Red break - } - + if (!$ComplianceAssignments) { - write-host "No Target Group Id specified, specify a valid Target Group Id" -f Red + Write-Host 'No Target Group Id specified, specify a valid Target Group Id' -f Red break - } - + $JSON = @" { @@ -367,24 +351,21 @@ Function Add-DeviceCompliancePolicyAssignment() { Write-Output $JSON $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)" - Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType "application/json" - - + Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType 'application/json' + } - + catch { - + $ex = $_.Exception - Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break } - } - + #################################################### Function Test-JSON() { @@ -402,30 +383,24 @@ NAME: Test-AuthHeader #> param ( - $JSON - ) try { - - $TestJSON = ConvertFrom-Json $JSON -ErrorAction Stop + $null = ConvertFrom-Json $JSON -ErrorAction Stop $validJson = $true - } catch { $validJson = $false $_.Exception - } if (!$validJson) { - + Write-Host "Provided JSON isn't in valid JSON format" -f Red break - } } @@ -434,11 +409,11 @@ NAME: Test-AuthHeader #region Authentication -write-host +Write-Host -if ($null -eq $User -or $User -eq "") { +if ([string]::IsNullOrWhiteSpace($User)) { - $User = Read-Host -Prompt "Please specify your user principal name for Azure Authentication" + $User = Read-Host -Prompt 'Please specify your user principal name for Azure Authentication' Write-Host } @@ -463,10 +438,10 @@ if (!(Test-Path "$ImportPath")) { #################################################### -Get-ChildItem $ImportPath -filter *.json | -Foreach-object { +Get-ChildItem $ImportPath -Filter *.json | +ForEach-Object { - $JSON_Data = Get-Content $_.FullName | Where-Object { $_ -notmatch "scheduledActionConfigurations@odata.context" } + $JSON_Data = Get-Content $_.FullName | Where-Object { $_ -notmatch 'scheduledActionConfigurations@odata.context' } # Excluding entries that are not required - id,createdDateTime,lastModifiedDateTime,version $JSON_Convert = $JSON_Data | ConvertFrom-Json | Select-Object -Property * -ExcludeProperty id, createdDateTime, lastModifiedDateTime, scheduledActionsForRule@odata.context @@ -483,7 +458,7 @@ Foreach-object { # Adding Scheduled Actions Rule to JSON - #$scheduledActionsForRule = '"scheduledActionsForRule":[{"ruleName":"PasswordRequired","scheduledActionConfigurations":[{"actionType":"block","gracePeriodHours":0,"notificationTemplateId":"","notificationMessageCCList":[]}]}]' + #$scheduledActionsForRule = '"scheduledActionsForRule":[{"ruleName":"PasswordRequired","scheduledActionConfigurations":[{"actionType":"block","gracePeriodHours":0,"notificationTemplateId":"","notificationMessageCCList":[]}]}]' #$JSON_Output = $JSON_Output.trimend("}") @@ -491,12 +466,12 @@ Foreach-object { # Joining the JSON together #$JSON_Output = $JSON_Output + $scheduledActionsForRule + "`r`n" + "}" - - write-host - write-host "Device Configuration Policy '$DisplayName' Found..." -ForegroundColor Yellow - write-host + + Write-Host + Write-Host "Device Configuration Policy '$DisplayName' Found..." -ForegroundColor Yellow + Write-Host $JSON_Output - write-host + Write-Host Write-Host "Adding Device Configuration Policy '$DisplayName'" -ForegroundColor Yellow Add-DeviceCompliancePolicy -JSON $JSON_Output @@ -511,16 +486,15 @@ Foreach-object { $ComplianceAssignments = @() - foreach ($AADGroup in $AADGroups ) - + foreach ($AADGroup in $AADGroups ) { - Write-Host "AAD Group Name:" $AADGroup.groupId -ForegroundColor Yellow - Write-Host "Assignment Type:" $AADGroup."@OData.type" -ForegroundColor Yellow + Write-Host 'AAD Group Name:' $AADGroup.groupId -ForegroundColor Yellow + Write-Host 'Assignment Type:' $AADGroup.'@OData.type' -ForegroundColor Yellow $TargetGroupId = (Get-AADGroup -GroupName $AADGroup.groupid) $TargetGroupId = $TargetGroupId.id - Write-Host "Included Group ID:" $TargetGroupID -ForegroundColor Yellow + Write-Host 'Included Group ID:' $TargetGroupID -ForegroundColor Yellow - $Assignment = $AADGroup."@OData.type" + $Assignment = $AADGroup.'@OData.type' $GroupAdd = @" { "target": { @@ -530,17 +504,14 @@ Foreach-object { }, "@ - + $ComplianceAssignments += $GroupAdd } - - Add-DeviceCompliancePolicyAssignment -ComplianceAssignments $ComplianceAssignments -CompliancePolicyId $CompliancePolicyId - - } - else - { - write-host "Device Compliance Policy:" $JSON_Convert.displayName "has already been created" -ForegroundColor Yellow + Add-DeviceCompliancePolicyAssignment -ComplianceAssignments $ComplianceAssignments -CompliancePolicyId $CompliancePolicyId } -} + else { + Write-Host 'Device Compliance Policy:' $JSON_Convert.displayName 'has already been created' -ForegroundColor Yellow + } +} diff --git a/SPE/Import-SPE-DeviceConfigScript.ps1 b/SPE/Import-SPE-DeviceConfigScript.ps1 index 4220079..88c38da 100644 --- a/SPE/Import-SPE-DeviceConfigScript.ps1 +++ b/SPE/Import-SPE-DeviceConfigScript.ps1 @@ -7,7 +7,7 @@ See LICENSE in the project root for license information. #> $ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path -$ImportPath = $ScriptDir+"\Scripts\SPE-DeviceConfig.ps1" +$ImportPath = $ScriptDir + '\Scripts\SPE-DeviceConfig.ps1' #################################################### @@ -25,7 +25,7 @@ Authenticates you with the Graph API interface NAME: Get-AuthToken #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -33,27 +33,27 @@ NAME: Get-AuthToken $User ) - $userUpn = New-Object "System.Net.Mail.MailAddress" -ArgumentList $User + $userUpn = New-Object 'System.Net.Mail.MailAddress' -ArgumentList $User $tenant = $userUpn.Host - Write-Host "Checking for AzureADPreview module..." + Write-Host 'Checking for AzureADPreview module...' - $AadModule = Get-Module -Name "AzureADPreview" -ListAvailable + $AadModule = Get-Module -Name 'AzureADPreview' -ListAvailable - if ($AadModule -eq $null) { + if ($null -eq $AadModule) { - Write-Host "AzureAD PowerShell module not found, looking for AzureADPreview" - $AadModule = Get-Module -Name "AzureADPreview" -ListAvailable + Write-Host 'AzureAD PowerShell module not found, looking for AzureADPreview' + $AadModule = Get-Module -Name 'AzureADPreview' -ListAvailable } - if ($AadModule -eq $null) { - write-host - write-host "AzureAD Powershell module not installed..." -f Red - write-host "Install by running 'Install-Module AzureAD' or 'Install-Module AzureADPreview' from an elevated PowerShell prompt" -f Yellow - write-host "Script can't continue..." -f Red - write-host + if ($null -eq $AadModule) { + Write-Host + Write-Host 'AzureAD Powershell module not installed...' -f Red + Write-Host "Install by running 'Install-Module AzureAD' or 'Install-Module AzureADPreview' from an elevated PowerShell prompt" -f Yellow + Write-Host "Script can't continue..." -f Red + Write-Host exit } @@ -62,27 +62,27 @@ NAME: Get-AuthToken if ($AadModule.count -gt 1) { - $Latest_Version = ($AadModule | select version | Sort-Object)[-1] + $Latest_Version = ($AadModule | Select-Object version | Sort-Object)[-1] - $aadModule = $AadModule | ? { $_.version -eq $Latest_Version.version } + $aadModule = $AadModule | Where-Object { $_.version -eq $Latest_Version.version } # Checking if there are multiple versions of the same module found if ($AadModule.count -gt 1) { - $aadModule = $AadModule | select -Unique + $aadModule = $AadModule | Select-Object -Unique } - $adal = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.dll" - $adalforms = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll" + $adal = Join-Path $AadModule.ModuleBase 'Microsoft.IdentityModel.Clients.ActiveDirectory.dll' + $adalforms = Join-Path $AadModule.ModuleBase 'Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll' } else { - $adal = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.dll" - $adalforms = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll" + $adal = Join-Path $AadModule.ModuleBase 'Microsoft.IdentityModel.Clients.ActiveDirectory.dll' + $adalforms = Join-Path $AadModule.ModuleBase 'Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll' } @@ -90,24 +90,24 @@ NAME: Get-AuthToken [System.Reflection.Assembly]::LoadFrom($adalforms) | Out-Null - $clientId = "d1ddf0e4-d672-4dae-b554-9d5bdfd93547" + $clientId = 'd1ddf0e4-d672-4dae-b554-9d5bdfd93547' - $redirectUri = "urn:ietf:wg:oauth:2.0:oob" + $redirectUri = 'urn:ietf:wg:oauth:2.0:oob' - $resourceAppIdURI = "https://graph.microsoft.com" + $resourceAppIdURI = 'https://graph.microsoft.com' $authority = "https://login.microsoftonline.com/$Tenant" try { - $authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority + $authContext = New-Object 'Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext' -ArgumentList $authority # https://msdn.microsoft.com/en-us/library/azure/microsoft.identitymodel.clients.activedirectory.promptbehavior.aspx # Change the prompt behaviour to force credentials each time: Auto, Always, Never, RefreshSession - $platformParameters = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.PlatformParameters" -ArgumentList "Auto" + $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.UserIdentifier' -ArgumentList ($User, 'OptionalDisplayableId') $authResult = $authContext.AcquireTokenAsync($resourceAppIdURI, $clientId, $redirectUri, $platformParameters, $userId).Result @@ -119,34 +119,28 @@ NAME: Get-AuthToken $authHeader = @{ 'Content-Type' = 'application/json' - 'Authorization' = "Bearer " + $authResult.AccessToken + 'Authorization' = 'Bearer ' + $authResult.AccessToken 'ExpiresOn' = $authResult.ExpiresOn } return $authHeader - } else { - Write-Host - Write-Host "Authorization Access Token is null, please re-run authentication..." -ForegroundColor Red + Write-Host 'Authorization Access Token is null, please re-run authentication...' -ForegroundColor Red Write-Host break - } - } catch { - write-host $_.Exception.Message -f Red - write-host $_.Exception.ItemName -f Red - write-host + Write-Host $_.Exception.Message -f Red + Write-Host $_.Exception.ItemName -f Red + Write-Host break - } - } #################################################### @@ -165,7 +159,7 @@ Adds a device management script from a URL in Intune .NOTES NAME: Add-DeviceManagementScript #> - [cmdletbinding()] + [CmdletBinding()] Param ( # Path or URL to Powershell-script to add to Intune [Parameter(Mandatory = $true)] @@ -178,7 +172,7 @@ NAME: Add-DeviceManagementScript [switch][bool]$URL = $false ) if ($URL -eq $true) { - $FileName = $File -split "/" + $FileName = $File -split '/' $FileName = $FileName[-1] $OutFile = "$env:TEMP\$FileName" try { @@ -201,7 +195,7 @@ NAME: Add-DeviceManagementScript } $FileName = Get-Item $File | Select-Object -ExpandProperty Name } - $B64File = [System.Convert]::ToBase64String([System.IO.File]::ReadAllBytes("$File")); + $B64File = [System.Convert]::ToBase64String([System.IO.File]::ReadAllBytes("$File")) if ($URL -eq $true) { Remove-Item $File -Force @@ -223,13 +217,13 @@ NAME: Add-DeviceManagementScript } "@ - $graphApiVersion = "Beta" - $DMS_resource = "deviceManagement/deviceManagementScripts" + $graphApiVersion = 'Beta' + $DMS_resource = 'deviceManagement/deviceManagementScripts' Write-Verbose "Resource: $DMS_resource" try { $uri = "https://graph.microsoft.com/$graphApiVersion/$DMS_resource" - Invoke-RestMethod -Uri $uri -Headers $authToken -Method Post -Body $JSON -ContentType "application/json" + Invoke-RestMethod -Uri $uri -Headers $authToken -Method Post -Body $JSON -ContentType 'application/json' } catch { @@ -239,14 +233,13 @@ NAME: Add-DeviceManagementScript $reader = New-Object System.IO.StreamReader($errorResponse) $reader.BaseStream.Position = 0 $reader.DiscardBufferedData() - $responseBody = $reader.ReadToEnd(); + $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 + Write-Host break } - } #################################################### @@ -264,7 +257,7 @@ Adds a device configuration policy assignment in Intune NAME: Add-DeviceConfigurationPolicyAssignment #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -272,21 +265,20 @@ NAME: Add-DeviceConfigurationPolicyAssignment $TargetGroupId ) - $graphApiVersion = "Beta" + $graphApiVersion = 'Beta' $Resource = "deviceManagement/deviceManagementScripts/$ScriptId/assign" try { if (!$ScriptId) { - write-host "No Script Policy Id specified, specify a valid Script Policy Id" -f Red + Write-Host 'No Script Policy Id specified, specify a valid Script Policy Id' -f Red break - } if (!$TargetGroupId) { - write-host "No Target Group Id specified, specify a valid Target Group Id" -f Red + Write-Host 'No Target Group Id specified, specify a valid Target Group Id' -f Red break } @@ -304,7 +296,7 @@ NAME: Add-DeviceConfigurationPolicyAssignment "@ $uri = "https://graph.microsoft.com/$graphApiVersion/$Resource" - Invoke-RestMethod -Uri $uri -Headers $authToken -Method Post -Body $JSON -ContentType "application/json" + Invoke-RestMethod -Uri $uri -Headers $authToken -Method Post -Body $JSON -ContentType 'application/json' } @@ -315,10 +307,10 @@ NAME: Add-DeviceConfigurationPolicyAssignment $reader = New-Object System.IO.StreamReader($errorResponse) $reader.BaseStream.Position = 0 $reader.DiscardBufferedData() - $responseBody = $reader.ReadToEnd(); + $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 + Write-Host break } @@ -340,7 +332,7 @@ Returns all users registered with Azure AD NAME: Get-AADGroup #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -350,8 +342,8 @@ NAME: Get-AADGroup ) # Defining Variables - $graphApiVersion = "v1.0" - $Group_resource = "groups" + $graphApiVersion = 'v1.0' + $Group_resource = 'groups' try { @@ -362,11 +354,10 @@ NAME: Get-AADGroup } - elseif ($GroupName -eq "" -or $GroupName -eq $null) { + elseif ([string]::IsNullOrWhiteSpace($GroupName)) { $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)" (Invoke-RestMethod -Uri $uri -Headers $authToken -Method Get).Value - } else { @@ -388,7 +379,7 @@ NAME: Get-AADGroup $GID = $Group.id $Group.displayName - write-host + Write-Host $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)/$GID/Members" (Invoke-RestMethod -Uri $uri -Headers $authToken -Method Get).Value @@ -406,14 +397,13 @@ NAME: Get-AADGroup $reader = New-Object System.IO.StreamReader($errorResponse) $reader.BaseStream.Position = 0 $reader.DiscardBufferedData() - $responseBody = $reader.ReadToEnd(); + $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 + Write-Host break } - } @@ -421,7 +411,7 @@ NAME: Get-AADGroup #region Authentication -write-host +Write-Host # Checking if authToken exists before running authentication if ($global:authToken) { @@ -434,14 +424,14 @@ if ($global:authToken) { if ($TokenExpires -le 0) { - write-host "Authentication Token expired" $TokenExpires "minutes ago" -ForegroundColor Yellow - write-host + Write-Host 'Authentication Token expired' $TokenExpires 'minutes ago' -ForegroundColor Yellow + Write-Host # Defining User Principal Name if not present - if ($User -eq $null -or $User -eq "") { + if ([string]::IsNullOrWhiteSpace($User)) { - $User = Read-Host -Prompt "Please specify your user principal name for Azure Authentication" + $User = Read-Host -Prompt 'Please specify your user principal name for Azure Authentication' Write-Host } @@ -455,9 +445,9 @@ if ($global:authToken) { else { - if ($User -eq $null -or $User -eq "") { + if ([string]::IsNullOrWhiteSpace($User)) { - $User = Read-Host -Prompt "Please specify your user principal name for Azure Authentication" + $User = Read-Host -Prompt 'Please specify your user principal name for Azure Authentication' Write-Host } @@ -474,12 +464,12 @@ else { # Setting application AAD Group to assign PowerShell scripts #$AADGroup = Read-Host -Prompt "Enter the Azure AD Group name where PowerShell scripts will be assigned" -$AADGroup = "Specialized Workstations" +$AADGroup = 'Specialized Workstations' $TargetGroupId = (Get-AADGroup -GroupName "$AADGroup").id -if ($TargetGroupId -eq $null -or $TargetGroupId -eq "") { +if ([string]::IsNullOrWhiteSpace($TargetGroupId)) { Write-Host "AAD Group - '$AADGroup' doesn't exist, please specify a valid AAD Group..." -ForegroundColor Red Write-Host @@ -489,15 +479,15 @@ if ($TargetGroupId -eq $null -or $TargetGroupId -eq "") { #################################################### -Write-Host "Adding Device Configuration Script from " $ImportPath -ForegroundColor Green +Write-Host 'Adding Device Configuration Script from ' $ImportPath -ForegroundColor Green -$Create_Local_Script = Add-DeviceManagementScript -File $ImportPath -Description "Specialized Device Config script" +$Create_Local_Script = Add-DeviceManagementScript -File $ImportPath -Description 'Specialized Device Config script' -Write-Host "Device Management Script created as" $Create_Local_Script.id -write-host -write-host "Assigning Device Management Script to AAD Group '$AADGroup'" -f Cyan +Write-Host 'Device Management Script created as' $Create_Local_Script.id +Write-Host +Write-Host "Assigning Device Management Script to AAD Group '$AADGroup'" -f Cyan $Assign_Local_Script = Add-DeviceManagementScriptAssignment -ScriptId $Create_Local_Script.id -TargetGroupId $TargetGroupId Write-Host "Assigned '$AADGroup' to $($Create_Local_Script.displayName)/$($Create_Local_Script.id)" -Write-Host \ No newline at end of file +Write-Host diff --git a/SPE/Import-SPE-DeviceConfiguration.ps1 b/SPE/Import-SPE-DeviceConfiguration.ps1 index cce22b4..fca8b2b 100644 --- a/SPE/Import-SPE-DeviceConfiguration.ps1 +++ b/SPE/Import-SPE-DeviceConfiguration.ps1 @@ -7,7 +7,7 @@ See LICENSE in the project root for license information. #> $ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path -$ImportPath = $ScriptDir + "\JSON\DeviceConfiguration" +$ImportPath = $ScriptDir + '\JSON\DeviceConfiguration' #################################################### @@ -26,7 +26,7 @@ Authenticates you with the Graph API interface NAME: Test-MgAuth #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -34,21 +34,21 @@ NAME: Test-MgAuth $User ) - $userUpn = New-Object "System.Net.Mail.MailAddress" -ArgumentList $User + $userUpn = New-Object 'System.Net.Mail.MailAddress' -ArgumentList $User $tenant = $userUpn.Host - Write-Host "Checking for Microsoft Graph module..." + Write-Host 'Checking for Microsoft Graph module...' - $MgModule = Get-Module -Name "Microsoft.Graph" -ListAvailable + $MgModule = Get-Module -Name 'Microsoft.Graph' -ListAvailable if ($null -eq $MgModule) { - write-host - write-host "Microsoft Graph Powershell module not installed..." -f Red - write-host "Install by running 'Install-Module Microsoft.Graph' or 'Install-Module Microsoft.Graph' from an elevated PowerShell prompt" -f Yellow - write-host "Script can't continue..." -f Red - write-host - + Write-Host + Write-Host 'Microsoft Graph Powershell module not installed...' -f Red + Write-Host "Install by running 'Install-Module Microsoft.Graph' or 'Install-Module Microsoft.Graph' from an elevated PowerShell prompt" -f Yellow + Write-Host "Script can't continue..." -f Red + Write-Host + } $scopes = @() @@ -56,21 +56,20 @@ NAME: Test-MgAuth ######################################### # Directory related scopes # ######################################### - $scopes += @("Device.Read.All", - "User.Read.All", - "GroupMember.ReadWrite.All", - "Group.ReadWrite.All", - "Directory.ReadWrite.All") + $scopes += @('Device.Read.All', + 'User.Read.All', + 'GroupMember.ReadWrite.All', + 'Group.ReadWrite.All', + 'Directory.ReadWrite.All') ######################################### # Device Management scopes # ######################################### - $scopes += @("DeviceManagementConfiguration.ReadWrite.All", - "DeviceManagementServiceConfig.ReadWrite.All", - "DeviceManagementRBAC.ReadWrite.All", - "DeviceManagementManagedDevices.ReadWrite.All", - "DeviceManagementApps.ReadWrite.All") - + $scopes += @('DeviceManagementConfiguration.ReadWrite.All', + 'DeviceManagementServiceConfig.ReadWrite.All', + 'DeviceManagementRBAC.ReadWrite.All', + 'DeviceManagementManagedDevices.ReadWrite.All', + 'DeviceManagementApps.ReadWrite.All') #$clientId = "d1ddf0e4-d672-4dae-b554-9d5bdfd93547" #$redirectUri = "urn:ietf:wg:oauth:2.0:oob" @@ -84,11 +83,11 @@ NAME: Test-MgAuth $ctx = Get-MgContext $org = Get-MgOrganization - $domains = $org.VerifiedDomains | select-object -ExpandProperty Name + $domains = $org.VerifiedDomains | Select-Object -ExpandProperty Name if ($ctx.Account.ToLower() -ne $userUpn.Address.ToLower() -or ($ctx.TenantId -ne $org.Id) -or $domains -notcontains $tenant) { - write-host "Unable to verify tenant or account" -f Red + Write-Host 'Unable to verify tenant or account' -f Red Disconnect-MgGraph - throw "Unable to continue due to validation" + throw 'Unable to continue due to validation' } # $authHeader = @{ @@ -100,9 +99,9 @@ NAME: Test-MgAuth # return $authHeader } catch { - write-host $_.Exception.Message -f Red - write-host $_.Exception.ItemName -f Red - write-host + Write-Host $_.Exception.Message -f Red + Write-Host $_.Exception.ItemName -f Red + Write-Host break } @@ -125,46 +124,40 @@ Adds a device configuration policy in Intune NAME: Add-DeviceConfigurationPolicy #> - [cmdletbinding()] + [CmdletBinding()] param ( $JSON ) - $graphApiVersion = "Beta" - $DCP_resource = "deviceManagement/deviceConfigurations" + $graphApiVersion = 'Beta' + $DCP_resource = 'deviceManagement/deviceConfigurations' Write-Verbose "Resource: $DCP_resource" try { - if ($JSON -eq "" -or $null -eq $JSON) { - - write-host "No JSON specified, please specify valid JSON for the Policy..." -f Red - + if ([string]::IsNullOrWhiteSpace($JSON)) { + Write-Host 'No JSON specified, please specify valid JSON for the Policy...' -f Red } else { - Test-JSON -JSON $JSON + Test-Json -Json $JSON $uri = "https://graph.microsoft.com/$graphApiVersion/$($DCP_resource)" - Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType "application/json" + Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType 'application/json' } } catch { - $ex = $_.Exception - Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break - } - } #################################################### @@ -183,7 +176,7 @@ Adds a device configuration policy assignment in Intune NAME: Add-DeviceConfigurationPolicyAssignment #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -192,32 +185,31 @@ NAME: Add-DeviceConfigurationPolicyAssignment $Assignment ) - $graphApiVersion = "Beta" + $graphApiVersion = 'Beta' $Resource = "deviceManagement/deviceConfigurations/$ConfigurationPolicyId/assignments" - + try { if (!$ConfigurationPolicyId) { - write-host "No Configuration Policy Id specified, specify a valid Configuration Policy Id" -f Red + Write-Host 'No Configuration Policy Id specified, specify a valid Configuration Policy Id' -f Red break } if (!$TargetGroupId) { - write-host "No Target Group Id specified, specify a valid Target Group Id" -f Red + Write-Host 'No Target Group Id specified, specify a valid Target Group Id' -f Red break - + } if (!$Assignment) { - write-host "No Assignment Type specified, specify a valid Assignment Type" -f Red + Write-Host 'No Assignment Type specified, specify a valid Assignment Type' -f Red break } - $ConfPolAssign = "$ConfigurationPolicyId" + "_" + "$TargetGroupId" - + $ConfPolAssign = "$ConfigurationPolicyId" + '_' + "$TargetGroupId" $JSON = @" @@ -230,21 +222,19 @@ NAME: Add-DeviceConfigurationPolicyAssignment "@ $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)" - Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType "application/json" + Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType 'application/json' } - + catch { $ex = $_.Exception - + Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break - } - } #################################################### @@ -264,15 +254,15 @@ Returns any device configuration policies configured in Intune NAME: Get-DeviceConfigurationPolicy #> - [cmdletbinding()] + [CmdletBinding()] param ( $name ) - $graphApiVersion = "Beta" - $DCP_resource = "deviceManagement/deviceConfigurations" + $graphApiVersion = 'Beta' + $DCP_resource = 'deviceManagement/deviceConfigurations' try { @@ -293,15 +283,12 @@ NAME: Get-DeviceConfigurationPolicy } catch { - $ex = $_.Exception - Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break - } } @@ -322,7 +309,7 @@ Returns all users registered with Azure AD NAME: Get-AADGroup #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -332,11 +319,11 @@ NAME: Get-AADGroup ) # Defining Variables - $graphApiVersion = "v1.0" - $Group_resource = "groups" + $graphApiVersion = 'v1.0' + $Group_resource = 'groups' # pseudo-group identifiers for all users and all devices - [string]$AllUsers = "acacacac-9df4-4c7d-9d50-4ef0226f57a9" - [string]$AllDevices = "adadadad-808e-44e2-905a-0b7873a8a531" + [string]$AllUsers = 'acacacac-9df4-4c7d-9d50-4ef0226f57a9' + [string]$AllDevices = 'adadadad-808e-44e2-905a-0b7873a8a531' try { @@ -344,14 +331,13 @@ NAME: Get-AADGroup $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)?`$filter=id eq '$id'" switch ( $id ) { - $AllUsers { $grp = [PSCustomObject]@{ displayName = "All users" }; $grp } - $AllDevices { $grp = [PSCustomObject]@{ displayName = "All devices" }; $grp } + $AllUsers { $grp = [PSCustomObject]@{ displayName = 'All users' }; $grp } + $AllDevices { $grp = [PSCustomObject]@{ displayName = 'All devices' }; $grp } default { (Invoke-MgGraphRequest -Uri $uri -Method Get).Value } } - } - elseif ($GroupName -eq "" -or $null -eq $GroupName) { + elseif ([string]::IsNullOrWhiteSpace($GroupName)) { $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)" (Invoke-MgGraphRequest -Uri $uri -Method Get).Value @@ -377,30 +363,24 @@ NAME: Get-AADGroup $GID = $Group.id $Group.displayName - write-host + Write-Host $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)/$GID/Members" (Invoke-MgGraphRequest -Uri $uri -Method Get).Value } - } - } - } catch { - $ex = $_.Exception - Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break } - } #################################################### @@ -420,45 +400,36 @@ NAME: Test-AuthHeader #> param ( - $JSON - ) try { - - $TestJSON = ConvertFrom-Json $JSON -ErrorAction Stop + $null = ConvertFrom-Json $JSON -ErrorAction Stop $validJson = $true - } catch { - $validJson = $false $_.Exception - } if (!$validJson) { - + Write-Host "Provided JSON isn't in valid JSON format" -f Red break - } - } #################################################### #region Authentication -write-host +Write-Host -if ($null -eq $User -or $User -eq "") { +if ([string]::IsNullOrWhiteSpace($User)) { - $User = Read-Host -Prompt "Please specify your user principal name for Azure Authentication" + $User = Read-Host -Prompt 'Please specify your user principal name for Azure Authentication' Write-Host - } Test-MgAuth -User $User @@ -495,8 +466,8 @@ if (!(Test-Path "$ImportPath")) { #################################################### -Get-ChildItem $ImportPath -filter *.json | -Foreach-object { +Get-ChildItem $ImportPath -Filter *.json | +ForEach-Object { $JSON_Data = Get-Content $_.FullName @@ -507,15 +478,14 @@ Foreach-object { $DuplicateDCP = Get-DeviceConfigurationPolicy -Name $JSON_Convert.displayName - If ($DuplicateDCP -eq $null) { $JSON_Output = $JSON_Convert | ConvertTo-Json -Depth 5 - - write-host - write-host "Device Configuration Policy '$DisplayName' Found..." -ForegroundColor Yellow - write-host + + Write-Host + Write-Host "Device Configuration Policy '$DisplayName' Found..." -ForegroundColor Yellow + Write-Host $JSON_Output - write-host + Write-Host Write-Host "Adding Device Configuration Policy '$DisplayName'" -ForegroundColor Yellow Add-DeviceConfigurationPolicy -JSON $JSON_Output @@ -524,33 +494,32 @@ Foreach-object { $DeviceConfigID = $DeviceConfigs.id - Write-Host "Device ConfigID '$DeviceConfigID'" -ForegroundColor Yellow + Write-Host "Device ConfigID '$DeviceConfigID'" -ForegroundColor Yellow Write-Host $AADGroups = $JSON_Convert.assignments.target - foreach ($AADGroup in $AADGroups ) - { - Write-Host "AAD Group Name:" $AADGroup.groupId -ForegroundColor Yellow - Write-Host "Assignment Type:" $AADGroup."@OData.type" -ForegroundColor Yellow - + foreach ($AADGroup in $AADGroups ) { + Write-Host 'AAD Group Name:' $AADGroup.groupId -ForegroundColor Yellow + Write-Host 'Assignment Type:' $AADGroup.'@OData.type' -ForegroundColor Yellow + $TargetGroupId = (Get-AADGroup -GroupName $AADGroup.groupid) - Write-Host "Included Group ID:" $TargetGroupID.Id -ForegroundColor Yellow - Add-DeviceConfigurationPolicyAssignment -ConfigurationPolicyId $DeviceConfigID -TargetGroupId $TargetGroupId.id -Assignment $AADGroup."@OData.type" + Write-Host 'Included Group ID:' $TargetGroupID.Id -ForegroundColor Yellow + Add-DeviceConfigurationPolicyAssignment -ConfigurationPolicyId $DeviceConfigID -TargetGroupId $TargetGroupId.id -Assignment $AADGroup.'@OData.type' } - + # Create exclude Group - + <#$ShortName = $JSON_Convert.displayName -replace "PAW-Global-2009-Intune-Configuration-", '' - $ExcludeGroup = "PAW-"+$ShortName+"-Exclude-Device" + $ExcludeGroup = "PAW-"+$ShortName+"-Exclude-Device" If (Get-AzureADGroup -SearchString $ExcludeGroup) { Write-Host Write-Host "AAD group" $ExcludeGroup "already exists!" -f Yellow Write-Host } Else { - + $MailNickName = $ShortName+"-G" - + try { $ExcludeTargetGroup = New-AzureADGroup -DisplayName $ExcludeGroup -Description $ExcludeGroup"-Group" -MailEnabled $false -SecurityEnabled $true -MailNickName $MailNickName @@ -563,15 +532,14 @@ Foreach-object { Write-Host } - } - + } + Write-Host "Excluded Group ID" $ExcludeTargetGroup.objectid Add-DeviceConfigurationPolicyAssignment -ConfigurationPolicyId $DeviceConfigID -TargetGroupId $ExcludeTargetGroup.objectid -Assignment "exclusionGroupAssignmentTarget" #> } - + else { - write-host "Device Configuration Profile:" $JSON_Convert.displayName "has already been created" -ForegroundColor Yellow + Write-Host 'Device Configuration Profile:' $JSON_Convert.displayName 'has already been created' -ForegroundColor Yellow } - -} \ No newline at end of file +} diff --git a/SPE/Import-SPE-DeviceConfigurationADMX.ps1 b/SPE/Import-SPE-DeviceConfigurationADMX.ps1 index 681e4fa..defa9fa 100644 --- a/SPE/Import-SPE-DeviceConfigurationADMX.ps1 +++ b/SPE/Import-SPE-DeviceConfigurationADMX.ps1 @@ -10,13 +10,12 @@ param ( #Change Conditional Access State, default is disabled #Options: enabled, disabled, enabledForReportingButNotEnforced - [String]$AADGroup = "Privileged Workstations" - + [String]$AADGroup = 'Privileged Workstations' ) #$AADGroup = "PAW-Global-Devices" $ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path -$ImportPath = $ScriptDir + "\JSON\DeviceConfigurationADMX" +$ImportPath = $ScriptDir + '\JSON\DeviceConfigurationADMX' function Test-MgAuth { @@ -32,7 +31,7 @@ Authenticates you with the Graph API interface NAME: Test-MgAuth #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -40,21 +39,21 @@ NAME: Test-MgAuth $User ) - $userUpn = New-Object "System.Net.Mail.MailAddress" -ArgumentList $User + $userUpn = New-Object 'System.Net.Mail.MailAddress' -ArgumentList $User $tenant = $userUpn.Host - Write-Host "Checking for Microsoft Graph module..." + Write-Host 'Checking for Microsoft Graph module...' - $MgModule = Get-Module -Name "Microsoft.Graph" -ListAvailable + $MgModule = Get-Module -Name 'Microsoft.Graph' -ListAvailable if ($null -eq $MgModule) { - write-host - write-host "Microsoft Graph Powershell module not installed..." -f Red - write-host "Install by running 'Install-Module Microsoft.Graph' or 'Install-Module Microsoft.Graph' from an elevated PowerShell prompt" -f Yellow - write-host "Script can't continue..." -f Red - write-host - + Write-Host + Write-Host 'Microsoft Graph Powershell module not installed...' -f Red + Write-Host "Install by running 'Install-Module Microsoft.Graph' or 'Install-Module Microsoft.Graph' from an elevated PowerShell prompt" -f Yellow + Write-Host "Script can't continue..." -f Red + Write-Host + } $scopes = @() @@ -62,21 +61,20 @@ NAME: Test-MgAuth ######################################### # Directory related scopes # ######################################### - $scopes += @("Device.Read.All", - "User.Read.All", - "GroupMember.ReadWrite.All", - "Group.ReadWrite.All", - "Directory.ReadWrite.All") + $scopes += @('Device.Read.All', + 'User.Read.All', + 'GroupMember.ReadWrite.All', + 'Group.ReadWrite.All', + 'Directory.ReadWrite.All') ######################################### # Device Management scopes # ######################################### - $scopes += @("DeviceManagementConfiguration.ReadWrite.All", - "DeviceManagementServiceConfig.ReadWrite.All", - "DeviceManagementRBAC.ReadWrite.All", - "DeviceManagementManagedDevices.ReadWrite.All", - "DeviceManagementApps.ReadWrite.All") - + $scopes += @('DeviceManagementConfiguration.ReadWrite.All', + 'DeviceManagementServiceConfig.ReadWrite.All', + 'DeviceManagementRBAC.ReadWrite.All', + 'DeviceManagementManagedDevices.ReadWrite.All', + 'DeviceManagementApps.ReadWrite.All') #$clientId = "d1ddf0e4-d672-4dae-b554-9d5bdfd93547" #$redirectUri = "urn:ietf:wg:oauth:2.0:oob" @@ -90,11 +88,11 @@ NAME: Test-MgAuth $ctx = Get-MgContext $org = Get-MgOrganization - $domains = $org.VerifiedDomains | select-object -ExpandProperty Name + $domains = $org.VerifiedDomains | Select-Object -ExpandProperty Name if ($ctx.Account.ToLower() -ne $userUpn.Address.ToLower() -or ($ctx.TenantId -ne $org.Id) -or $domains -notcontains $tenant) { - write-host "Unable to verify tenant or account" -f Red + Write-Host 'Unable to verify tenant or account' -f Red Disconnect-MgGraph - throw "Unable to continue due to validation" + throw 'Unable to continue due to validation' } # $authHeader = @{ @@ -106,19 +104,18 @@ NAME: Test-MgAuth # return $authHeader } catch { - write-host $_.Exception.Message -f Red - write-host $_.Exception.ItemName -f Red - write-host + Write-Host $_.Exception.Message -f Red + Write-Host $_.Exception.ItemName -f Red + Write-Host break } - } - + #################################################### - + Function Create-GroupPolicyConfigurations() { - + <# .SYNOPSIS This function is used to add an device configuration policy using the Graph API REST interface @@ -130,49 +127,46 @@ Adds a device configuration policy in Intune .NOTES NAME: Add-DeviceConfigurationPolicy #> - - [cmdletbinding()] + + [CmdletBinding()] param ( $DisplayName ) - + $jsonCode = @" { "description":"", "displayName":"$($DisplayName)" } "@ - - $graphApiVersion = "Beta" - $DCP_resource = "deviceManagement/groupPolicyConfigurations" + + $graphApiVersion = 'Beta' + $DCP_resource = 'deviceManagement/groupPolicyConfigurations' Write-Verbose "Resource: $DCP_resource" - + try { - + $uri = "https://graph.microsoft.com/$graphApiVersion/$($DCP_resource)" - $responseBody = Invoke-MgGraphRequest -Uri $uri -Method Post -Body $jsonCode -ContentType "application/json" - - + $responseBody = Invoke-MgGraphRequest -Uri $uri -Method Post -Body $jsonCode -ContentType 'application/json' + } - + catch { - + $ex = $_.Exception - Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break - + } $responseBody.id } - - + Function Create-GroupPolicyConfigurationsDefinitionValues() { - + <# .SYNOPSIS This function is used to get device configuration policies from the Graph API REST interface @@ -184,55 +178,50 @@ Function Create-GroupPolicyConfigurationsDefinitionValues() { .NOTES NAME: Get-GroupPolicyConfigurations #> - - [cmdletbinding()] + + [CmdletBinding()] Param ( - + [string]$GroupPolicyConfigurationID, $JSON - + ) - - $graphApiVersion = "Beta" - + + $graphApiVersion = 'Beta' + $DCP_resource = "deviceManagement/groupPolicyConfigurations/$($GroupPolicyConfigurationID)/definitionValues" - write-host $DCP_resource + Write-Host $DCP_resource try { - if ($JSON -eq "" -or $null -eq $JSON) { - - write-host "No JSON specified, please specify valid JSON for the Device Configuration Policy..." -f Red - + if ([string]::IsNullOrWhiteSpace($JSON)) { + + Write-Host 'No JSON specified, please specify valid JSON for the Device Configuration Policy...' -f Red } - + else { - - Test-JSON -JSON $JSON - + + Test-Json -Json $JSON + $uri = "https://graph.microsoft.com/$graphApiVersion/$($DCP_resource)" - Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType "application/json" + Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType 'application/json' } - + } - + catch { - $ex = $_.Exception - Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break - + } - } - - + #################################################### Function Get-GroupPolicyConfigurations() { - + <# .SYNOPSIS This function is used to get device configuration policies from the Graph API REST interface @@ -244,37 +233,31 @@ Returns any device configuration policies configured in Intune .NOTES NAME: Get-GroupPolicyConfigurations #> - - [cmdletbinding()] + + [CmdletBinding()] param ( $name ) - - $graphApiVersion = "Beta" - $DCP_resource = "deviceManagement/groupPolicyConfigurations" - + $graphApiVersion = 'Beta' + $DCP_resource = 'deviceManagement/groupPolicyConfigurations' + try { - + $uri = "https://graph.microsoft.com/$graphApiVersion/$($DCP_resource)" (Invoke-MgGraphRequest -Uri $uri -Method Get).Value | Where-Object { ($_.'displayName') -eq ("$Name") } - } - + catch { - $ex = $_.Exception - Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break - } - } #################################################### @@ -293,7 +276,7 @@ Adds a device configuration policy assignment in Intune NAME: Add-DeviceConfigurationPolicyAssignment #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -302,33 +285,30 @@ NAME: Add-DeviceConfigurationPolicyAssignment $Assignment ) - $graphApiVersion = "Beta" + $graphApiVersion = 'Beta' $Resource = "deviceManagement/groupPolicyConfigurations/$ConfigurationPolicyId/assignments" - + try { if (!$ConfigurationPolicyId) { - write-host "No Configuration Policy Id specified, specify a valid Configuration Policy Id" -f Red + Write-Host 'No Configuration Policy Id specified, specify a valid Configuration Policy Id' -f Red break - } if (!$TargetGroupId) { - write-host "No Target Group Id specified, specify a valid Target Group Id" -f Red + Write-Host 'No Target Group Id specified, specify a valid Target Group Id' -f Red break - } if (!$Assignment) { - write-host "No Assignment Type specified, specify a valid Assignment Type" -f Red + Write-Host 'No Assignment Type specified, specify a valid Assignment Type' -f Red break } # $ConfPolAssign = "$ConfigurationPolicyId" + "_" + "$TargetGroupId" - $JSON = @" { @@ -340,22 +320,19 @@ NAME: Add-DeviceConfigurationPolicyAssignment "@ $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)" - Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType "application/json" + Invoke-MgGraphRequest -Uri $uri -Method Post -Body $JSON -ContentType 'application/json' } - - catch { + catch { $ex = $_.Exception - Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break } - } #################################################### @@ -374,7 +351,7 @@ Returns all users registered with Azure AD NAME: Get-AADGroup #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -384,11 +361,11 @@ NAME: Get-AADGroup ) # Defining Variables - $graphApiVersion = "v1.0" - $Group_resource = "groups" + $graphApiVersion = 'v1.0' + $Group_resource = 'groups' # pseudo-group identifiers for all users and all devices - [string]$AllUsers = "acacacac-9df4-4c7d-9d50-4ef0226f57a9" - [string]$AllDevices = "adadadad-808e-44e2-905a-0b7873a8a531" + [string]$AllUsers = 'acacacac-9df4-4c7d-9d50-4ef0226f57a9' + [string]$AllDevices = 'adadadad-808e-44e2-905a-0b7873a8a531' try { @@ -396,14 +373,13 @@ NAME: Get-AADGroup $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)?`$filter=id eq '$id'" switch ( $id ) { - $AllUsers { $grp = [PSCustomObject]@{ displayName = "All users" }; $grp } - $AllDevices { $grp = [PSCustomObject]@{ displayName = "All devices" }; $grp } + $AllUsers { $grp = [PSCustomObject]@{ displayName = 'All users' }; $grp } + $AllDevices { $grp = [PSCustomObject]@{ displayName = 'All devices' }; $grp } default { (Invoke-MgGraphRequest -Uri $uri -Method Get).Value } } - } - elseif ($GroupName -eq "" -or $null -eq $GroupName) { + elseif ([string]::IsNullOrWhiteSpace($GroupName)) { $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)" (Invoke-MgGraphRequest -Uri $uri -Method Get).Value @@ -429,37 +405,31 @@ NAME: Get-AADGroup $GID = $Group.id $Group.displayName - write-host + Write-Host $uri = "https://graph.microsoft.com/$graphApiVersion/$($Group_resource)/$GID/Members" (Invoke-MgGraphRequest -Uri $uri -Method Get).Value } - } - } - } catch { $ex = $_.Exception - Write-Host "Response content:`n$($ex.Response.Content.ReadAsStringAsync().Result)" -f Red Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)" - write-host + Write-Host break - } - } #################################################### Function Test-JSON() { - + <# .SYNOPSIS This function is used to test if the JSON passed to a REST Post request is valid @@ -471,57 +441,48 @@ Test if the JSON is valid before calling the Graph REST interface .NOTES NAME: Test-AuthHeader #> - + param ( - $JSON - ) - + try { - - $TestJSON = ConvertFrom-Json $JSON -ErrorAction Stop + $null = ConvertFrom-Json $JSON -ErrorAction Stop $validJson = $true - } - + catch { - $validJson = $false $_.Exception - } - + if (!$validJson) { - Write-Host "Provided JSON isn't in valid JSON format" -f Red break - } - + } - + #################################################### - + #region Authentication - -write-host - + +Write-Host + # Defining User Principal Name if not present -if ($null -eq $User -or $User -eq "") { - - $User = Read-Host -Prompt "Please specify your user principal name for Azure Authentication" +if ([string]::IsNullOrWhiteSpace($User)) { + + $User = Read-Host -Prompt 'Please specify your user principal name for Azure Authentication' Write-Host } - + # Getting the authorization token Test-MgAuth -User $User - - + #endregion - + #################################################### - + # Replacing quotes for Test-Path $ImportPath = $ImportPath.replace('"', '') @@ -532,7 +493,6 @@ if (!(Test-Path "$ImportPath")) { Write-Host "Script can't continue..." -ForegroundColor Red Write-Host break - } #################################################### @@ -540,7 +500,7 @@ if (!(Test-Path "$ImportPath")) { $TargetGroupId = (Get-AADGroup | Where-Object { $_.displayName -eq $AADGroup }).id -if ($null -eq $TargetGroupId -or $TargetGroupId -eq "") { +if ([string]::IsNullOrWhiteSpace($TargetGroupId)) { Write-Host "AAD Group - '$AADGroup' doesn't exist, please specify a valid AAD Group..." -ForegroundColor Red Write-Host @@ -550,45 +510,37 @@ if ($null -eq $TargetGroupId -or $TargetGroupId -eq "") { #################################################### - - -Get-ChildItem $ImportPath -filter *.json | - -ForEach-Object { +Get-ChildItem $ImportPath -Filter *.json | ForEach-Object { $Policy_Name = $_.Name $Policy_Name = $Policy_Name.Substring(0, $Policy_Name.Length - 5) - + $DuplicateDCP = Get-GroupPolicyConfigurations -Name $Policy_Name - If ($DuplicateDCP -eq $null) - { + If ($DuplicateDCP -eq $null) { $GroupPolicyConfigurationID = Create-GroupPolicyConfigurations -DisplayName $Policy_Name $JSON_Data = Get-Content $_.FullName $JSON_Convert = $JSON_Data | ConvertFrom-Json $JSON_Convert | ForEach-Object { $_ - - $JSON_Output = Convertto-Json -Depth 5 $_ + + $JSON_Output = ConvertTo-Json -Depth 5 $_ Write-Host $JSON_Output - Create-GroupPolicyConfigurationsDefinitionValues -JSON $JSON_Output -GroupPolicyConfigurationID $GroupPolicyConfigurationID + Create-GroupPolicyConfigurationsDefinitionValues -JSON $JSON_Output -GroupPolicyConfigurationID $GroupPolicyConfigurationID } - Write-Host "####################################################################################################" -ForegroundColor Green - Write-Host "Policy: " $Policy_Name "created" -ForegroundColor Green - Write-Host "####################################################################################################" -ForegroundColor Green + Write-Host '####################################################################################################' -ForegroundColor Green + Write-Host 'Policy: ' $Policy_Name 'created' -ForegroundColor Green + Write-Host '####################################################################################################' -ForegroundColor Green $DeviceConfigs = Get-GroupPolicyConfigurations -name $Policy_Name $DeviceConfigID = $DeviceConfigs.id - - Add-GroupPolicyConfigurationPolicyAssignment -ConfigurationPolicyId $DeviceConfigID -TargetGroupId $TargetGroupId -Assignment "groupAssignmentTarget" - } - else - { - write-host "Device Configuration ADMX Profile:" $Policy_Name "has already been created" -ForegroundColor Yellow + Add-GroupPolicyConfigurationPolicyAssignment -ConfigurationPolicyId $DeviceConfigID -TargetGroupId $TargetGroupId -Assignment 'groupAssignmentTarget' } + else { + Write-Host 'Device Configuration ADMX Profile:' $Policy_Name 'has already been created' -ForegroundColor Yellow + } } - diff --git a/SPE/MasterScript-SPE.ps1 b/SPE/MasterScript-SPE.ps1 index 8196b0b..22065ec 100644 --- a/SPE/MasterScript-SPE.ps1 +++ b/SPE/MasterScript-SPE.ps1 @@ -23,7 +23,7 @@ Authenticates you with the Graph API interface NAME: Test-MgAuth #> - [cmdletbinding()] + [CmdletBinding()] param ( @@ -31,21 +31,20 @@ NAME: Test-MgAuth $User ) - $userUpn = New-Object "System.Net.Mail.MailAddress" -ArgumentList $User + $userUpn = New-Object 'System.Net.Mail.MailAddress' -ArgumentList $User $tenant = $userUpn.Host - Write-Host "Checking for Microsoft Graph module..." + Write-Host 'Checking for Microsoft Graph module...' - $MgModule = Get-Module -Name "Microsoft.Graph" -ListAvailable + $MgModule = Get-Module -Name 'Microsoft.Graph' -ListAvailable if ($null -eq $MgModule) { - write-host - write-host "Microsoft Graph Powershell module not installed..." -f Red - write-host "Install by running 'Install-Module Microsoft.Graph' or 'Install-Module Microsoft.Graph' from an elevated PowerShell prompt" -f Yellow - write-host "Script can't continue..." -f Red - write-host - + Write-Host + Write-Host 'Microsoft Graph Powershell module not installed...' -f Red + Write-Host "Install by running 'Install-Module Microsoft.Graph' or 'Install-Module Microsoft.Graph' from an elevated PowerShell prompt" -f Yellow + Write-Host "Script can't continue..." -f Red + Write-Host } $scopes = @() @@ -53,21 +52,20 @@ NAME: Test-MgAuth ######################################### # Directory related scopes # ######################################### - $scopes += @("Device.Read.All", - "User.Read.All", - "GroupMember.ReadWrite.All", - "Group.ReadWrite.All", - "Directory.ReadWrite.All") + $scopes += @('Device.Read.All', + 'User.Read.All', + 'GroupMember.ReadWrite.All', + 'Group.ReadWrite.All', + 'Directory.ReadWrite.All') ######################################### # Device Management scopes # ######################################### - $scopes += @("DeviceManagementConfiguration.ReadWrite.All", - "DeviceManagementServiceConfig.ReadWrite.All", - "DeviceManagementRBAC.ReadWrite.All", - "DeviceManagementManagedDevices.ReadWrite.All", - "DeviceManagementApps.ReadWrite.All") - + $scopes += @('DeviceManagementConfiguration.ReadWrite.All', + 'DeviceManagementServiceConfig.ReadWrite.All', + 'DeviceManagementRBAC.ReadWrite.All', + 'DeviceManagementManagedDevices.ReadWrite.All', + 'DeviceManagementApps.ReadWrite.All') #$clientId = "d1ddf0e4-d672-4dae-b554-9d5bdfd93547" #$redirectUri = "urn:ietf:wg:oauth:2.0:oob" @@ -81,11 +79,11 @@ NAME: Test-MgAuth $ctx = Get-MgContext $org = Get-MgOrganization - $domains = $org.VerifiedDomains | select-object -ExpandProperty Name + $domains = $org.VerifiedDomains | Select-Object -ExpandProperty Name if ($ctx.Account.ToLower() -ne $userUpn.Address.ToLower() -or ($ctx.TenantId -ne $org.Id) -or $domains -notcontains $tenant) { - write-host "Unable to verify tenant or account" -f Red + Write-Host 'Unable to verify tenant or account' -f Red Disconnect-MgGraph - throw "Unable to continue due to validation" + throw 'Unable to continue due to validation' } # $authHeader = @{ @@ -97,49 +95,40 @@ NAME: Test-MgAuth # return $authHeader } catch { - write-host $_.Exception.Message -f Red - write-host $_.Exception.ItemName -f Red - write-host + Write-Host $_.Exception.Message -f Red + Write-Host $_.Exception.ItemName -f Red + Write-Host break } - } - + #################################################### - - $User = Read-Host -Prompt "Please specify your user principal name for Microsoft Authentication" - - Test-MgAuth -user $user - - #################################################### - - +$User = Read-Host -Prompt 'Please specify your user principal name for Microsoft Authentication' + +Test-MgAuth -user $user + +#################################################### -write-host "Adding Device Configuration Profiles" +Write-Host 'Adding Device Configuration Profiles' . $ScriptDir/Import-SPE-DeviceConfiguration.ps1 Start-Sleep -s 5 -write-host "Adding Device Compliance Policies" +Write-Host 'Adding Device Compliance Policies' . $ScriptDir/Import-SPE-DeviceCompliancePolicies.ps1 Start-Sleep -s 5 -write-host "Adding Edge Browser Policy" +Write-Host 'Adding Edge Browser Policy' . $ScriptDir/Import-SPE-DeviceConfigurationADMX.ps1 -Start-Sleep -s 5 +Start-Sleep -Seconds 5 #Write-host "Importing Device Config PowerShell script" #. $ScriptDir/Import-SPE-DeviceConfigScript.ps1 - - - - - diff --git a/SPE/Readme.md b/SPE/Readme.md index c2e6ac0..8eb9fba 100644 --- a/SPE/Readme.md +++ b/SPE/Readme.md @@ -1,6 +1,6 @@ # Specialized Profile configuration -The scripts for configuring the Specialized security baseline are located in this folder. +The scripts for configuring the Specialized security baseline are located in this folder. Before the scripts can be run install Azure AD powershell module on your device ```powershell @@ -12,24 +12,22 @@ Set-ExecutionPolicy remotesigned ``` [**MasterScript_SPE.PS1**](MasterScript-SPE.ps1) - This script is used to import the Compliance policies, Configuration profiles used to apply the Specialized Profile settings - + To import the Specialized Profile configuration settings into your tenant Open powershell console - Navigate to SPE folder in Repo + Navigate to SPE folder in Repo ```powershell .\MasterScript-SPE.ps1 ``` - + Enter **username** and **password** of an account that has Intune Administrator (preferred) or Global Admin privilege Wait for the import process to complete. The MasterScript_SPE.ps1 file calls the following scripts to import the Compliance Policies, Configuration Profiles - - [**Import-SPE-DeviceCompliancePolicies.ps1**](Import-SPE-DeviceCompliancePolicies.ps1) - This scripts imports the three device compliance policies for the Specialized profile. Three policies are used to ensure that Conditional Access does not prevent a user from being able to access resources. Refer to [Windows 10 and later settings to mark devices as compliant or not compliant using Intune](https://docs.microsoft.com/en-us/mem/intune/protect/compliance-policy-create-windows) - + 1. [Specialized Compliance ATP](JSON/DeviceCompliance/SPE-Compliance-ATP.json) policy is used to feed the Threat Intelligence data from Microsoft Defender for Endpoint into the devices compliance state so its signals can be used as part of the Conditional Access evaluation process. 2. [Specialized Compliance Delayed](JSON/DeviceCompliance/SPE-Compliance-Delayed.json) policy applies a more complete set of compliance settings to the device but its application is delayed by 24 hours. this is because the device health attestation that is required to assess policies like BitLocker and Secure Boot is only calculated once a device has rebooted and then might take a number of hours to process whether the device is compliant or not. @@ -52,4 +50,3 @@ The Specialized policy also includes rules to allow OneDrive and Microsoft Teams [**Import-SPE-DeviceConfigurationADMX.ps1**](JSON/DeviceConfigurationADMX/Specialized-Edge%20Version%2085%20-%20Computer.json) this script is used to import the Device Configuration ADMX Template profile that configures Microsoft Edge security settings. 1. [Specialized-Edge Version 85 - Computer](JSON/DeviceConfigurationADMX/Specialized-Edge%20Version%2085%20-%20Computer.json) applies administrative policies that control features in Microsoft Edge version 77 and later, refer to [Microsoft Edge - Policies](https://docs.microsoft.com/en-us/DeployEdge/microsoft-edge-policies) or more details of the settings applied using the profile. - diff --git a/SPE/Scripts/SPE-DeviceConfig.ps1 b/SPE/Scripts/SPE-DeviceConfig.ps1 index 5f53c34..01f9c47 100644 --- a/SPE/Scripts/SPE-DeviceConfig.ps1 +++ b/SPE/Scripts/SPE-DeviceConfig.ps1 @@ -19,17 +19,17 @@ Function Start-Log { [Parameter(HelpMessage = 'Deletes existing file if used with the -DeleteExistingFile switch')] [switch]$DeleteExistingFile ) - + Try { If (!(Test-Path $FilePath)) { ## Create the log file New-Item $FilePath -Type File -Force | Out-Null } - + If ($DeleteExistingFile) { Remove-Item $FilePath -Force } - + ## Set the global variable to be used as the FilePath for all subsequent Write-Log ## calls in this session $script:ScriptLogFilePath = $FilePath @@ -47,7 +47,7 @@ Function Start-Log { param ( [Parameter(Mandatory = $true)] [string]$Message, - + [Parameter()] [ValidateSet(1, 2, 3)] [int]$LogLevel = 1, @@ -81,7 +81,7 @@ NAME: Is-VM [CmdletBinding()] Param () - + Begin { Write-Log -Message "$($MyInvocation.InvocationName) function..." } @@ -96,7 +96,7 @@ NAME: Is-VM $True } else { - Write-Log -Message "Virtual string not found" + Write-Log -Message "Virtual string not found" $False } } @@ -123,7 +123,7 @@ NAME: Is-VM } Else { Write-Host "Machine is a physical device" - + #Enable Hibernate Write-Log -Message "Enabling Hibernation" $command = "C:\Windows\System32\PowerCfg.exe" @@ -170,7 +170,7 @@ NAME: Is-VM #Write-Warning "$($env:computername.ToUpper()) : $($_.Exception.message)" #Exit } - + $command = "C:\Windows\System32\PowerCfg.exe" $args = "/Change standby-timeout-ac 60" $workDir = "C:\Windows\System32" @@ -202,7 +202,7 @@ NAME: Is-VM } Catch { Write-Log -Message "Error changing registry: $($_.Exception.message)" - Write-Warning "Error: $($_.Exception.message)" + Write-Warning "Error: $($_.Exception.message)" Exit } Finally { @@ -220,27 +220,22 @@ NAME: Is-VM } Catch { Write-Log -Message "Error changing AppLocker DLL rule registry key: $($_.Exception.message)" - Write-Warning "Error: $($_.Exception.message)" + Write-Warning "Error: $($_.Exception.message)" Exit } Finally { Write-Log -Message "Finished changing AppLocker DLL rule registry key" } #endregion Configure AppLocker DLL rule registry key - + #region Configure additional Defender for Endpoint security recommendations that cannot be set in Configuration Profiles #Handle registry changes - - - Write-Log -Message "Configuring additional Defender for Endpoint security recommendations that cannot be set in Configuration Profiles" - # Require users to elevate when setting a network's location - prevent changing from Public to Private firewall profile - New-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Network Connections" -Name NC_StdDomainUserSetLocation -Value 1 -PropertyType DWORD -Force - Write-Log -Message "Require users to elevate when setting a network's location - prevent changing from Public to Private firewall profile registry update successfully applied" - # Prevent saving of network credentials + + # Prevent saving of network credentials New-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Control\Lsa -Name DisableDomainCreds -Value 1 -PropertyType DWORD -Force Write-Log -Message "Prevent saving of network credentials registry update successfully applied" # Prevent changing proxy config - + #region Disable Network Location Wizard - prevents users from setting network location as Private and therefore increasing the attack surface exposed in Windows Firewall #region Disable Network Location Wizard #Handle registry changes @@ -260,7 +255,7 @@ NAME: Is-VM } Catch { Write-Log -Message "Error changing registry: $($_.Exception.message)" - Write-Warning "Error: $($_.Exception.message)" + Write-Warning "Error: $($_.Exception.message)" Exit } Finally { @@ -310,7 +305,7 @@ NAME: Is-VM } #endregion Remove WindowsMediaPlayer - + #region RegistryChanges - Set W32Time Parameter Type to NTP #Handle registry changes $registryPath = "HKLM:\SYSTEM\CurrentControlSet\Services\W32Time\Parameters" @@ -332,7 +327,7 @@ NAME: Is-VM } Catch { Write-Log -Message "Error changing registry: $($_.Exception.message)" - Write-Warning "Error: $($_.Exception.message)" + Write-Warning "Error: $($_.Exception.message)" Exit } Finally { @@ -361,14 +356,14 @@ NAME: Is-VM } Catch { Write-Log -Message "Error changing registry: $($_.Exception.message)" - Write-Warning "Error: $($_.Exception.message)" + Write-Warning "Error: $($_.Exception.message)" Exit } Finally { Write-Log -Message "Set Auto Time Sync Service to Automatic start" } #endregion RegistryChanges - Set Auto Time Sync Service to Automatic start - + <#region Remove Internet Explorer 11 try {