param ( [switch] $CheckComplianceOnly = $false ) # Variables [System.Int32]$policyBinaryTimeoutSeconds = 300 [System.Int32]$waitBatchSeconds = 5 [System.Int32]$maxWaitSeconds = 300 [string]$miPolicyBinaryPathRoot = "$env:windir\System32" if(-not ([Environment]::Is64BitProcess)) { $miPolicyBinaryPathRoot = "$env:windir\Sysnative" } [string]$miPolicyBinaryPath = Join-Path -Path $miPolicyBinaryPathRoot -ChildPath "AppLocker\ManagedInstaller.AppLocker" [string]$SccmMiPolicy = @" "@ function MergeAppLockerPolicy([string]$policyXml) { $policyFile = '.\AppLockerPolicy.xml' $policyXml | Out-File $policyFile Write-Host "Merging and setting AppLocker policy" Set-AppLockerPolicy -XmlPolicy $policyFile -Merge -ErrorAction SilentlyContinue Remove-Item $policyFile } function VerifyCompliance([xml]$policy) { $result = $false $miNode = $policy.AppLockerPolicy.ChildNodes | Where-Object{$_.Type -eq 'ManagedInstaller'} $intunememi = $false #Intune Management Extenstions Managed Installer var initialization if(-not $miNode) { Write-Host('Policy does not contain any managed installers') } else { $IntuneMENode = $miNode.ChildNodes | Where-Object{($_.LocalName -eq 'FilePublisherRule') -and ($_.Name -eq 'MICROSOFT.MANAGEMENT.SERVICES.INTUNEWINDOWSAGENT.EXE version 1.38.300.1 exactly in MICROSOFT® INTUNE™ from O=MICROSOFT CORPORATION, L=REDMOND, S=WASHINGTON, C=US')} if(-not $IntuneMENode) { Write-Host('Policy does not have IntuneME managed installer policy.') } else { Write-Host('Policy has an IntuneME managed installer policy.') $intunememi = $true } } $result = $intunememi return $result } # Execution flow starts here # Get and load the current effective AppLocker policy try { [xml]$effectivePolicyXml = Get-AppLockerPolicy -Effective -Xml -ErrorVariable ev -ErrorAction SilentlyContinue } catch { Write-Error('Get-AppLockerPolicy failed. ' + $_.Exception.Message) exit 10 } # Check if it contains MI policy and if the MI policy has rules for Ccmsetup/CcmExec try { $compliant = VerifyCompliance($effectivePolicyXml) } catch { Write-Error('Failed to verify AppLocker policy compliance. ' + $_.Exception.Message) exit 12 } if($compliant) { Write-Host("AppLocker policy is compliant") exit 0 } Write-Host("AppLocker policy is not compliant") if($CheckComplianceOnly) { exit 2 } # Set the policy try { MergeAppLockerPolicy($SccmMiPolicy) } catch { Write-Error('Failed to merge AppLocker policy. ' + $_.Exception.Message) exit 14 } # Start services Write-Host 'Starting services' Start-Process -FilePath "C:\WINDOWS\System32\sc.exe" -ArgumentList "start gpsvc" Start-Process -FilePath "C:\WINDOWS\System32\appidtel.exe" -ArgumentList "start -mionly" [System.Int32]$waitedSeconds = 0 # Check service state, wait up to 1 minute while($waitedSeconds -lt $maxWaitSeconds) { Start-Sleep -Seconds $waitBatchSeconds $waitedSeconds += $waitBatchSeconds if(-not ((Get-Service AppIDSvc).Status -eq 'Running')) { Write-Host 'AppID Service is not fully started yet.' continue } if(-not ((Get-Service appid).Status -eq 'Running')) { Write-Host 'AppId Driver Service is not fully started yet.' continue } if(-not ((Get-Service applockerfltr).Status -eq 'Running')) { Write-Host 'AppLocker Filter Driver Service is not fully started yet.' continue } break } if (-not ($waitedSeconds -lt $maxWaitSeconds)) { Write-Error 'Time-out on waiting for services to start.' exit 1 } reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GPExtensions\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}" /v MaxNoGPOListChangesInterval /t REG_DWORD /d 960 /f stop-service gpsvc -force -ErrorAction SilentlyContinue start-service gpsvc -ErrorAction SilentlyContinue gpupdate.exe /force # Wait for policy update if(test-path $miPolicyBinaryPath) { $previousPolicyBinaryTimeStamp = (Get-ChildItem $miPolicyBinaryPath).LastWriteTime Write-Host ('There is an existing ManagedInstaller policy binary (LastWriteTime: {0})' -f $previousPolicyBinaryTimeStamp.ToString('yyyy-MM-dd HH:mm')) } if($previousPolicyBinaryTimeStamp) { $action = 'updated' $condition = '$previousPolicyBinaryTimeStamp -lt (Get-ChildItem $miPolicyBinaryPath).LastWriteTime' } else { $action = 'created' $condition = 'test-path $miPolicyBinaryPath' } Write-Host "Waiting for policy binary to be $action" $startTime = get-date while(-not (Invoke-Expression $condition)) { Start-Sleep -Seconds $waitBatchSeconds if((new-timespan $startTime $(get-date)).TotalSeconds -ge $policyBinaryTimeoutSeconds) { Write-Error "Policy binary has not been $action within $policyBinaryTimeoutSeconds seconds" exit 1 } } Write-Host ('Policy binary was created after {0:mm} minutes {0:ss} seconds' -f (new-timespan $startTime $(get-date))) # Check compliance again try { [xml]$effectivePolicyXml = Get-AppLockerPolicy -Effective -Xml -ErrorVariable ev -ErrorAction SilentlyContinue } catch { Write-Error('Get-AppLockerPolicy failed. ' + $_.Exception.Message) exit 10 } # Check if it contains MI policy and if the MI policy has rules for Ccmsetup/CcmExec try { $compliant = VerifyCompliance($effectivePolicyXml) } catch { Write-Error('Failed to verify AppLocker policy compliance. ' + $_.Exception.Message) exit 12 } if($compliant -eq $false) { Write-Error("AppLocker policy is not compliant") exit 1 } Write-Host 'AppLocker with Managed Installer successfully enabled'