$outputPath = "$env:temp\CollectedData\Intune\Commands\General" $x = if (-not (Test-Path $outputPath)) { mkdir $outputPath -Force} msinfo32.exe /NFO "$outputPath\$($env:COMPUTERNAME)_msinfo32.nfo" msinfo32.exe /report "$outputPath\$($env:COMPUTERNAME)_msinfo32.txt" dsregcmd /status function RunCommand { Param ([string]$cmdToRun) echo "`r`n===========================================`r`n`t`t $cmdToRun `r`n===========================================`r`n" try { Invoke-Expression($cmdToRun) -ErrorAction Stop } catch { $error[0].ToString()} } RunCommand "whoami" RunCommand "whoami /upn" RunCommand "whoami /all" RunCommand "whoami /logonid" RunCommand "whoami /fqdn" RunCommand "net localgroup administrators" # dsregcmd_debug # Attempt to run using local tools first $ErrorActionPreference = "Stop" $Error.Clear() $line = "`*" * 120 try { $TimeToRun = (Get-Date ).AddSeconds(3) $taskName = "dsregcmd debug" $folderPath = "$env:temp\CollectedData\Intune\Commands\General" $filepath = Join-Path $folderPath $($env:ComputerName + "_dsregcmd_debug.txt") # Create folder if it does not exist for uploader if ( -not ( Test-Path $folderPath -ErrorAction SilentlyContinue) ) { $nil = mkdir $folderPath -Force } $line | Out-File $filepath -Force -Encoding ascii "Starting dsregcmd /debug using Scheduled Task as SYSTEM`r`n" | Out-File $filepath -Append -Force -Encoding ascii $line | Out-File $filepath -Force -Append -Encoding ascii $Trigger= New-ScheduledTaskTrigger -At $TimeToRun -Once $User= "NT AUTHORITY\SYSTEM" $Action= New-ScheduledTaskAction -Execute "cmd.exe" -Argument "/c dsregcmd /debug >> $filepath" $nil = Register-ScheduledTask -TaskName $taskName -Trigger $Trigger -User $User -Action $Action -RunLevel Highest –Force $nil = Start-ScheduledTask -TaskName $taskName sleep 9 #cleanup $nil = Unregister-ScheduledTask -TaskName $taskName -TaskPath "\" -PassThru -Confirm:$false } # second chance - we'll attempt to download PSExec catch { "$line" | Out-File $filepath -Append -Force -Encoding ascii "`r`n" * 3 | Out-File $filepath -Append -Force -Encoding ascii "Scheduled Task failed, trying to download PSExec.`r`n$error" | Out-File $filepath -Append -Force -Encoding ascii "`r`n" * 3 | Out-File $filepath -Append -Force -Encoding ascii "$line" | Out-File $filepath -Append -Force -Encoding ascii [string]$downloadLocation = "https://live.sysinternals.com/psexec.exe" [string]$psexec = "" $myproxy = "No proxy (direct connection)" if ( Get-Command psexec.exe -ErrorAction SilentlyContinue ) { $psexec = $(Get-Command psexec.exe).Source } elseif (Get-Item ".\psexec.exe" -ErrorAction SilentlyContinue) { $psexec = Join-Path $pwd psexec.exe } else { try { if ( [System.Net.WebProxy]::GetDefaultProxy().Address -eq $null ) { Invoke-WebRequest -Uri $downLoadLocation -OutFile .\psexec.exe } else { $myproxy = ([System.Net.WebProxy]::GetDefaultProxy().Address.AbsoluteURI) Invoke-WebRequest -Uri $downLoadLocation -OutFile .\psexec.exe -Proxy $myproxy } $psexec = Join-Path $pwd psexec.exe } catch { "One Data Collector was unable to download psexec.exe from $downLoadLocation (proxy settings: $myproxy. Please download PSExec manually to run dsregcmd /debug."| Out-File $filepath -Append -Force $err| Out-File $filepath -Append -Force } } try { & "$psexec" -nobanner -accepteula -s -e dsregcmd /debug | Out-File $filepath -Append -Force -Encoding ascii } catch [System.Management.Automation.RemoteException] { # expected, do nothing "." * 120 | Out-File $filepath -Append -Force -Encoding ascii } catch { "`r`n" * 3 | Out-File $filepath -Append -Force -Encoding ascii "$line" | Out-File $filepath -Append -Force -Encoding ascii "An error occured running psexec.`r`n $error" | Out-File $filepath -Append -Force -Encoding ascii "*" * 120 | Out-File $filepath -Append -Force -Encoding ascii } } # BasicSystemInfo Function GetAgeDescription($TimeSpan, [switch] $Localized) { $Age = $TimeSpan if ($Age.Days -gt 0) { $AgeDisplay = $Age.Days.ToString() if ($Age.Days -gt 1) { if ($Localized.IsPresent) { $AgeDisplay += " " + $UtilsCTSStrings.ID_Days } else { $AgeDisplay += " Days" } } else { if ($Localized.IsPresent) { $AgeDisplay += " " + $UtilsCTSStrings.ID_Day } else { $AgeDisplay += " Day" } } } else { if ($Age.Hours -gt 0) { if ($AgeDisplay.Length -gt 0) {$AgeDisplay += " "} $AgeDisplay = $Age.Hours.ToString() if ($Age.Hours -gt 1) { if ($Localized.IsPresent) { $AgeDisplay += " " + $UtilsCTSStrings.ID_Hours } else { $AgeDisplay += " Hours" } } else { if ($Localized.IsPresent) { $AgeDisplay += " " + $UtilsCTSStrings.ID_Hour } else { $AgeDisplay += " Hour" } } } if ($Age.Minutes -gt 0) { if ($AgeDisplay.Length -gt 0) {$AgeDisplay += " "} $AgeDisplay += $Age.Minutes.ToString() if ($Age.Minutes -gt 1) { if ($Localized.IsPresent) { $AgeDisplay += " " + $UtilsCTSStrings.ID_Minutes } else { $AgeDisplay += " Minutes" } } else { if ($Localized.IsPresent) { $AgeDisplay += " " + $UtilsCTSStrings.ID_Minute } else { $AgeDisplay += " Minute" } } } if ($Age.Seconds -gt 0) { if ($AgeDisplay.Length -gt 0) {$AgeDisplay += " "} $AgeDisplay += $Age.Seconds.ToString() if ($Age.Seconds -gt 1) { if ($Localized.IsPresent) { $AgeDisplay += " " + $UtilsCTSStrings.ID_Seconds } else { $AgeDisplay += " Seconds" } } else { if ($Localized.IsPresent) { $AgeDisplay += " " + $UtilsCTSStrings.ID_Second } else { $AgeDisplay += " Second" } } } if (($Age.TotalSeconds -lt 1)) { if ($AgeDisplay.Length -gt 0) {$AgeDisplay += " "} $AgeDisplay += $Age.TotalSeconds.ToString() if ($Localized.IsPresent) { $AgeDisplay += " " + $UtilsCTSStrings.ID_Seconds } else { $AgeDisplay += " Seconds" } } } Return $AgeDisplay } $OS_Summary = new-object PSObject # Operating System Summary $CS_Summary = new-object PSObject # Computer System Summary $WMIOS = $null $error.Clear() $WMIOS = get-wmiobject -class "win32_operatingsystem" -ErrorAction SilentlyContinue if ($Error.Count -ne 0) { $errorMessage = $Error[0].Exception.Message $errorCode = "0x{0:X}" -f $Error[0].Exception.ErrorCode "Error" + $errorCode + ": $errorMessage connecting to $MachineName" | WriteTo-StdOut $Error.Clear() } # Get all data from WMI if ($WMIOS -ne $null) { #if WMIOS is null - means connection failed. Abort script execution. $WMICS = get-wmiobject -Class "win32_computersystem" $WMIProcessor = get-wmiobject -Class "Win32_processor" $OSProcessorArch = $WMIOS.OSArchitecture $OSProcessorArchDisplay = " " + $OSProcessorArch } #There is no easy way to detect the OS Architecture on pre-Windows Vista Platform if ($OSProcessorArch -eq $null) { if ($MachineName -eq ".") { #Local Computer $OSProcessorArch = $Env:PROCESSOR_ARCHITECTURE } else { $RemoteReg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("LocalMachine",$MachineName) $OSProcessorArch = ($RemoteReg.OpenSubKey("SYSTEM\CurrentControlSet\Control\Session Manager\Environment")).GetValue("PROCESSOR_ARCHITECTURE") } if ($OSProcessorArch -ne $null) { switch ($OSProcessorArch) { "AMD64" {$ProcessorArchDisplay = " (64-bit)"} "i386" {$ProcessorArchDisplay = " (32-bit)"} "IA64" {$ProcessorArchDisplay = " (64-bit - Itanium)"} default {$ProcessorArchDisplay = " ($ProcessorArch)"} } } else { $OSProcessorArchDisplay = "" } } # Build OS Summary # Name add-member -inputobject $OS_Summary -membertype noteproperty -name "Machine Name" -value $WMIOS.CSName add-member -inputobject $OS_Summary -membertype noteproperty -name "OS Name" -value ($WMIOS.Caption + " Service Pack " + $WMIOS.ServicePackMajorVersion + $OSProcessorArchDisplay) add-member -inputobject $OS_Summary -membertype noteproperty -name "Build" -value ($WMIOS.Version) add-member -inputobject $OS_Summary -membertype noteproperty -name "Time Zone/Offset" -value ((Get-WmiObject -Class Win32_TimeZone).Caption + "/" + $WMIOS.CurrentTimeZone) # Install Date #$date = [DateTime]::ParseExact($wmios.InstallDate.Substring(0, 8), "yyyyMdd", $null) #add-member -inputobject $OS_Summary -membertype noteproperty -name "Install Date" -value $date.ToShortDateString() add-member -inputobject $OS_Summary -membertype noteproperty -name "Last Reboot/Uptime" -value ($WMIOS.ConvertToDateTime($WMIOS.LastBootUpTime).ToString() + " (" + (GetAgeDescription(New-TimeSpan $WMIOS.ConvertToDateTime($WMIOS.LastBootUpTime))) + ")") # Build Computer System Summary # Name add-member -inputobject $CS_Summary -membertype noteproperty -name "Computer Model" -value $WMICS.model $numProcs=0 $ProcessorType = "" $ProcessorName = "" $ProcessorDisplayName= "" foreach ($WMIProc in $WMIProcessor) { $ProcessorType = $WMIProc.manufacturer switch ($WMIProc.NumberOfCores) { 1 {$numberOfCores = "single core"} 2 {$numberOfCores = "dual core"} 4 {$numberOfCores = "quad core"} $null {$numberOfCores = "single core"} default { $numberOfCores = $WMIProc.NumberOfCores.ToString() + " core" } } switch ($WMIProc.Architecture) { 0 {$CpuArchitecture = "x86"} 1 {$CpuArchitecture = "MIPS"} 2 {$CpuArchitecture = "Alpha"} 3 {$CpuArchitecture = "PowerPC"} 6 {$CpuArchitecture = "Itanium"} 9 {$CpuArchitecture = "x64"} } if ($ProcessorDisplayName.Length -eq 0) { $ProcessorDisplayName = " " + $numberOfCores + " $CpuArchitecture processor " + $WMIProc.name } else { if ($ProcessorName -ne $WMIProc.name) { $ProcessorDisplayName += "/ " + " " + $numberOfCores + " $CpuArchitecture processor " + $WMIProc.name } } $numProcs += 1 $ProcessorName = $WMIProc.name } $ProcessorDisplayName = "$numProcs" + $ProcessorDisplayName add-member -inputobject $CS_Summary -membertype noteproperty -name "Processor(s)" -value $ProcessorDisplayName if ($WMICS.Domain -ne $null) { add-member -inputobject $CS_Summary -membertype noteproperty -name "Machine Domain" -value $WMICS.Domain } if ($WMICS.DomainRole -ne $null) { switch ($WMICS.DomainRole) { 0 {$RoleDisplay = "Workstation"} 1 {$RoleDisplay = "Member Workstation"} 2 {$RoleDisplay = "Standalone Server"} 3 {$RoleDisplay = "Member Server"} 4 {$RoleDisplay = "Backup Domain Controller"} 5 {$RoleDisplay = "Primary Domain controller"} } add-member -inputobject $CS_Summary -membertype noteproperty -name "Role" -value $RoleDisplay } if ($WMIOS.ProductType -eq 1) { #Client $AntivirusProductWMI = get-wmiobject -query "select companyName, displayName, versionNumber, productUptoDate, onAccessScanningEnabled FROM AntivirusProduct" -Namespace "root\SecurityCenter" if ($AntivirusProductWMI.displayName -ne $null) { $AntivirusDisplay= $AntivirusProductWMI.companyName + " " + $AntivirusProductWMI.displayName + " version " + $AntivirusProductWMI.versionNumber if ($AntivirusProductWMI.onAccessScanningEnabled) { $AVScanEnabled = "Enabled" } else { $AVScanEnabled = "Disabled" } if ($AntivirusProductWMI.productUptoDate) { $AVUpToDate = "Yes" } else { $AVUpToDate = "No" } #$AntivirusStatus = "OnAccess Scan: $AVScanEnabled" + ". Up to date: $AVUpToDate" add-member -inputobject $OS_Summary -membertype noteproperty -name "Anti Malware" -value $AntivirusDisplay } else { $AntivirusProductWMI = get-wmiobject -Namespace root\SecurityCenter2 -Class AntiVirusProduct if ($AntivirusProductWMI -ne $null) { add-member -inputobject $OS_Summary -membertype noteproperty -name "AntiMalware" -value $AntivirusProductWMI.displayName } } } $SystemPolicies = get-itemproperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" $EnableLUA = $SystemPolicies.EnableLUA $ConsentPromptBehaviorAdmin = $SystemPolicies.ConsentPromptBehaviorAdmin if ($EnableLUA) { $UACDisplay = "Enabled" switch ($ConsentPromptBehaviorAdmin) { 0 {$UACDisplay += " / UAC Mode: ID_UACNoPrompt"} 1 {$UACDisplay += " / UAC Mode: ID_UACPromptCredentials"} 2 {$UACDisplay += " / UAC Mode: ID_UACPromptConsent"} 5 {$UACDisplay += " / UAC Mode: ID_UACPromptConsentApp"} } } else { $UACDisplay = "Disabled" } add-member -inputobject $OS_Summary -membertype noteproperty -name "UAC" -value $UACDisplay add-member -inputobject $OS_Summary -membertype noteproperty -name "Username" -value ($Env:USERDOMAIN + "\" + $Env:USERNAME) $versions = @{ "19042" = "2010" "19041" = "2004" "18363" = "1909" "18362" = "1903" "17763" = "1809" "17134" = "1803" "16299" = "1709" "15063" = "1703" "14393" = "1607" "10586" = "1511" "10240" = "RTM" } $marketingNames = @{ "19042" = "October 2020 Update" "19041" = "May 2020 Update" "18363" = "November 2019 Update" "18362" = "May 2019 Update" "17763" = "October 2018 Update" "17134" = "April 2018 Update" "16299" = "Fall Creators Update" "15063" = "Creators Update" "14393" = "Anniversary Update" "10586" = "November Update" "10240" = "RTM" } $codeNames = @{ "19042" = "20H2" "19041" = "20H1" "18363" = "19H2" "18362" = "19H1" "17763" = "Redstone 5" "17134" = "Redstone 4" "16299" = "Redstone 3" "15063" = "Redstone 2" "14393" = "Redstone 1" "10586" = "Threshold 2" "10240" = "Threshold 1" } $Win10Version = Get-WmiObject -Class Win32_OperatingSystem #System Center Advisor Information $SCAKey = "HKLM:\SOFTWARE\Microsoft\SystemCenterAdvisor" if (Test-Path($SCAKey)) { $CustomerID = (Get-ItemProperty -Path $SCAKey).CustomerID if ($CustomerID -ne $null) { "System Center Advisor detected. Customer ID: $CustomerID" | writeto-stdout $SCA_Summary = New-Object PSObject $SCA_Summary | add-member -membertype noteproperty -name "Customer ID" -value $CustomerID $SCA_Summary | ConvertTo-Xml2 | update-diagreport -id ("01_SCACustomerSummary") -name "System Center Advisor" -verbosity Informational } } # Joined/Registered status $ds = dsregcmd /status [bool]$isRegistered = [bool]($ds -match "Work account") [bool]$isJoined = [bool]($ds -match "AzureAdJoined : YES") $Policies = "HKLM:\SOFTWARE\Microsoft\IntuneManagementExtension\Policies" if (test-path $Policies) { foreach ($Policy in (dir $Policies)) { if ([guid]::Empty -ne $Policy.PSChildName) { $UserID = $Policy.PSChildName } } } # Regsistered User and Tenant info # Sort so we always get the most current in case there are orphaned certs if ( (Get-ChildItem Cert:\LocalMachine\My).count -eq 0) { Write-Output "No certs in Local Machine store, skipping" } else { $cert = (dir Cert:\LocalMachine\My\ | where { $_.Issuer -match "CN=MS-Organization-Access" } | Sort-Object -Property NotBefore -Descending)[0] } # use to find registry path $thumbPrint = $cert.Thumbprint # Get the tenant name from the registry if (Test-Path HKLM:\SYSTEM\CurrentControlSet\Control\CloudDomainJoin\JoinInfo\$($thumbPrint)) { $userEmail = (Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Control\CloudDomainJoin\JoinInfo\$($thumbPrint)).UserEmail $tenant = $userEmail.Split('@')[1] } $MachineID = "Unknown" $DeviceName = "Unknown" $MachineIDContainer = dir hklm:SOFTWARE\Microsoft\Enrollments -Recurse | Where {$_.Name -match 'MS DM Server'} if ($MachineIDContainer){ $MachineID = $MachineIDContainer| Get-ItemPropertyValue -Name EntDMID $DeviceName = $MachineIDContainer| Get-ItemPropertyValue -Name EntDeviceName } $SubscriptionID = $ds -match "SubscriptionID : (.+)" # Start reporting $OS_Summary | fl if ($Win10Version.BuildNumber -gt 19042) { "**** WARNING: Beta version of Windows detected: Build $($Win10Version.version) *****"} "Windows build: $($Win10Version.version)" "Windows version: $($versions[$Win10Version.BuildNumber])" "Windows name: $($marketingNames[$Win10Version.BuildNumber])" "Windows code name: $($codeNames[$Win10Version.BuildNumber])" if ($isRegistered) { "Azure AD status: Registered" } elseif ($isJoined) { "Azure AD status: Joined" } else { "Azure AD status: Not registered/joined or unknown" } if ($UserID) { "UserID: $UserID" } if ($MachineID) { "Intune Device ID: $MachineID"} if ($DeviceName) { "Device Name: $DeviceName"} if ($SubscriptionID) { "SubscriptionID: $SubscriptionID" } if ($tenant) { "Tenant name: $tenant"} if ($userEmail) { "User UPN: $userEmail"} $CS_Summary | fl systeminfo.exe "BIOS Information" Get-WmiObject -Class Win32_BIOS echo "`r`n===========================================`r`n`t`t wmic product list brief `r`n===========================================`r`n" wmic product list brief echo "`r`n===========================================`r`n`t`t netsh winhttp show proxy `r`n===========================================`r`n" netsh winhttp show proxy function RunCommand { Param ([string]$cmdToRun) $line = "`r`n================================================================================================" echo "`r`n$line`r`n`t`t $cmdToRun $line`r`n" try { Invoke-Expression($cmdToRun) -ErrorAction Stop } catch { $error[0].ToString()} } RunCommand "manage-bde -status" RunCommand "Get-BitLockerVolume |fl * -Force" RunCommand "Get-Tpm" RunCommand "Manage-bde -protectors -get $env:systemdrive" RunCommand "'SelfTest:' $(Get-Tpm | Select-Object -ExpandProperty SelfTest)" RunCommand "Get-TpmEndorsementKeyInfo" RunCommand "Get-TpmSupportedFeature -Verbose" RunCommand "Get-CimInstance -ClassName Win32_Tpm -Namespace 'root\CIMV2\Security\MicrosoftTpm' " RunCommand "Get-CimInstance -ClassName Win32_baseboard -Namespace 'root\CIMV2' " RunCommand "reagentc /info 2>NUL" RunCommand "bcdedit /enum all" RunCommand "gwmi win32_bios | fl *" RunCommand "Get-Service tpm |fl *" RunCommand "powercfg /a" RunCommand "Confirm-SecureBootUEFI" # Registry keys RunCommand "Get-Item HKLM:\SOFTWARE\Microsoft\PolicyManager\current\device\BitLocker" RunCommand "Get-ChildItem HKLM:\SOFTWARE\Microsoft\PolicyManager\default\Bitlocker" RunCommand "Get-Item HKLM:\SOFTWARE\Policies\Microsoft\FVE" RunCommand "Get-ChildItem HKLM:\SOFTWARE\Microsoft\PolicyManager\Providers\*\Bitlocker -Recurse" # Disk config RunCommand "Get-Disk | fl *" RunCommand "gwmi Win32_DiskPartition" RunCommand "gwmi -class win32_logicaldisk" RunCommand "gwmi -class win32_volume" function RunCommand { Param ([string]$cmdToRun) echo "`r`n===========================================`r`n`t`t $cmdToRun `r`n===========================================`r`n" try { Invoke-Expression($cmdToRun) -ErrorAction Stop } catch { $error[0].ToString()} } RunCommand "netsh advfirewall show allprofiles" RunCommand "netsh advfirewall show allprofiles" RunCommand "netsh advfirewall show global" RunCommand "Get-NetFirewallProfile" RunCommand "Get-NetFirewallRule" RunCommand "Get-NetFirewallSetting" #Gather Defender files $mpc = "$env:ProgramFiles\Windows Defender\MpCmdRun.exe" if (Test-Path -Path $mpc) { $output = &$mpc -getfiles $cabPath = $output -match "MpSupportFiles.cab" # Get the full path to the cab $cabPath = $cabPath -replace "^.* *(.:.*)", "`$1" $outputPath = "$env:temp\CollectedData\Intune\Commands\Defender" $x = if (-not (Test-Path $outputPath)) { mkdir $outputPath -Force} copy $cabPath $outPutPath\WindowsDefender-SupportFiles.cab } function RunCommand { Param ([string]$cmdToRun) echo "`r`n===========================================`r`n`t`t $cmdToRun `r`n===========================================`r`n" try { Invoke-Expression($cmdToRun) -ErrorAction Stop } catch { $error[0].ToString()} } RunCommand -cmdToRun "hostname" RunCommand -cmdToRun "ipconfig /all" RunCommand -cmdToRun "arp -a" RunCommand -cmdToRun "nbtstat -n" RunCommand -cmdToRun "netstat -ano" RunCommand -cmdToRun "netstat -anob" RunCommand -cmdToRun "reg.exe query HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters /v EnableTCPChimney" RunCommand -cmdToRun "reg.exe query HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters /v EnableRSS" RunCommand -cmdToRun "reg.exe query HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters /v EnableTCPA" RunCommand -cmdToRun "reg.exe query HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters /v DisableTaskOffload" if ($OSVersion.Major -ge 6) { RunCommand -cmdToRun "netsh int tcp show global" RunCommand -cmdToRun "netsh int ipv4 show offload" RunCommand -cmdToRun "netstat -nato -p tcp" -FileDescription "TCP/IP Basic Information" -CollectFile $true } else { RunCommand -cmdToRun "netstat -ano -p tcp" } RunCommand -cmdToRun "net config workstation" if ((Get-Service "lanmanserver").Status -eq 'Running') { RunCommand -cmdToRun "net config server" RunCommand -cmdToRun "net share" RunCommand -cmdToRun "net statistics server" } RunCommand -cmdToRun "net sessions" RunCommand -cmdToRun "net use" RunCommand -cmdToRun "net accounts" RunCommand -cmdToRun "net statistics workstation" echo "`r`n===========================================`r`n`t`t Get-Process | select Name, FileVersion, Path, ProductVersion | ft -auto -wrap `r`n===========================================`r`n" Get-Process | select Name, FileVersion, Path, ProductVersion | ft -auto -wrap echo "`r`n===========================================`r`n`t`t Get-WmiObject Win32_PnPSignedDriver| select DeviceName, DriverVersion | ft -auto -wrap`r`n===========================================`r`n" Get-WmiObject Win32_PnPSignedDriver| select DeviceName, DriverVersion | ft -auto -wrap if (Test-Path $env:windir\syswow64\drivers) { get-childitem $env:windir\syswow64\drivers -recurse -file | select DeviceName, DriverVersion | ft -auto -wrap } else { "$env:windir\syswow64\drivers not found. This is normal on an x86 system." } echo "`r`n===========================================`r`n`t`t Get-WmiObject Win32_PnPSignedDriver | select DeviceName, DriverVersion | ft -auto`r`n===========================================`r`n" Get-WmiObject Win32_PnPSignedDriver | select DeviceName, DriverVersion | ft -auto echo "`r`n===========================================`r`n`t`t schtasks.exe /Query `r`n===========================================`r`n" schtasks.exe /Query $outputPath = "$env:temp\CollectedData\Intune\Commands\Windows Update" $x = if (-not (Test-Path $outputPath)) { mkdir $outputPath -Force} Get-WindowsUpdateLog -Logpath $outputPath\$($env:COMPUTERNAME)_WindowsUpdate.log gpresult.exe /V echo "`r`n===========================================`r`n`t`t Get-WindowsOptionalFeature -Online | where {$_.State -eq `"Enabled`"} `r`n===========================================`r`n" Get-WindowsOptionalFeature -Online | where {$_.State -eq "Enabled"} echo "======= netsh int show int ======" netsh int show int echo "======= netsh int ipv4 show int ======" netsh int ipv4 show int echo "======= netsh int ipv4 show addresses ======" netsh int ipv4 show addresses echo "======= netsh int ipv4 show ipaddresses ======" netsh int ipv4 show ipaddresses echo "======= netsh int ipv4 show compartments ======" netsh int ipv4 show compartments echo "======= netsh int ipv4 show dnsservers ======" netsh int ipv4 show dnsservers echo "======= netsh int ipv4 show winsservers ======" netsh int ipv4 show winsservers echo "======= netsh int ipv4 show dynamicportrange tcp ======" netsh int ipv4 show dynamicportrange tcp echo "======= netsh int ipv4 show dynamicportrange udp ======" netsh int ipv4 show dynamicportrange udp echo "======= netsh int ipv4 show global ======" netsh int ipv4 show global echo "======= netsh int ipv4 show icmpstats ======" netsh int ipv4 show icmpstats echo "======= netsh int ipv4 show ipstats ======" netsh int ipv4 show ipstats echo "======= netsh int ipv4 show joins ======" netsh int ipv4 show joins echo "======= netsh int ipv4 show offload ======" netsh int ipv4 show offload echo "======= netsh int ipv4 show route ======" netsh int ipv4 show route echo "======= netsh int ipv4 show subint ======" netsh int ipv4 show subint echo "======= netsh int ipv4 show tcpconnections ======" netsh int ipv4 show tcpconnections echo "======= netsh int ipv4 show tcpstats ======" netsh int ipv4 show tcpstats echo "======= netsh int ipv4 show udpconnections ======" netsh int ipv4 show udpconnections echo "======= netsh int ipv4 show udpstats ======" netsh int ipv4 show udpstats echo "======= netsh int ipv4 show destinationcache ======" netsh int ipv4 show destinationcache echo "======= netsh int ipv4 show ipnettomedia ======" netsh int ipv4 show ipnettomedia echo "======= netsh int ipv4 show neighbors ======" netsh int ipv4 show neighbors $x = MdmDiagnosticsTool.exe -out "$pwd\$($env:COMPUTERNAME)_" $outputPath = "$env:temp\CollectedData\Intune\Commands\General" $x = if (-not (Test-Path $outputPath)) { mkdir $outputPath -Force} ren "$pwd\$($env:COMPUTERNAME)_\MDMDiagReport.html" "$($env:COMPUTERNAME)_MDMDiagReport.html" ren "$pwd\$($env:COMPUTERNAME)_\MDMDiagReport.xml" "$($env:COMPUTERNAME)_MDMDiagReport.xml" $x = move .\$($env:COMPUTERNAME)_\*MDMDiagReport.* $outputPath -Force rmdir "$($env:COMPUTERNAME)_" -Force -Recurse $uniqueURLs = (dsregcmd /status) | ForEach-Object { if ($_ -match ".*https://(\w+.+?)\/") { $matches[1]} } | Get-Unique $uniqueURLs | ForEach-Object { Test-NetConnection -Port 443 $_ -ErrorAction SilentlyContinue} echo "`r`n===========================================`r`n`t`t w32tm /tz `r`n===========================================`r`n" w32tm /tz #NDES function Get-FilesOlderThan { Param ([int]$days = 2, [string]$path = $pwd ) $DaysAgo = (Get-Date).AddDays(-($days)) $files = @() $files = Get-ChildItem $path | where { $_.CreationTime -gt $DaysAgo } # get latest file if none meet our criteria if ((Test-Path $path) -and (-not $files) ) { $newestFile = Get-ChildItem $path |Sort-Object LastAccessTime -Descending | Select-Object -First 1 $files += $newestFile } $files } if (Test-Path HKLM:\SOFTWARE\Microsoft\MicrosoftIntune\NDESConnector) { $installFolder = (Get-ItemProperty HKLM:\SOFTWARE\Microsoft\MicrosoftIntune\NDESConnector).InstallFolder $copyPath = "$env:temp\CollectedData\Intune\Files\NDES" if ($installFolder) { $ndesPaths = @( "$installFolder\NDESPolicyModule\Logs\NDESPlugin.log", "$installFolder\NDESConnectorSvc\Logs\Logs\NDESConnector*", "$installFolder\NDESConnectorSvc\Logs\Logs\CertificateRegistrationPoint*", "$installFolder\NDESConnectorUI\NDESConnectorUI.log", "$installFolder\NDESConnectorUI\Logs\*", "C:\inetpub\logs\LogFiles\W3SVC1\u_ex*.log" "$installFolder\NDESPolicyModule\Logs\NDESPlugin.log", "C:\NDESConnectorSetup\*.log", "$env:programfiles\Microsoft Configuration Manager\logs\ndes*" ) if (-not(test-path $copyPath) ) { $x = mkdir $copyPath -Force } ForEach ($ndesPath in $ndesPaths) { if (Test-Path $ndesPath) { $filesToCollect = Get-FilesOlderThan -path $ndesPath -days 3 foreach ($fileToCollect in $filesToCollect) { copy $fileToCollect $copyPath} } } copy "C:\NDESConnectorSetupMSI\*" $copyPath } } certutil.exe #ConfigMgr function Get-FilesOlderThan { Param ([int]$days = 2, [string]$path = $pwd ) $DaysAgo = (Get-Date).AddDays(-($days)) $files = @() $files = Get-ChildItem $path | where { $_.CreationTime -gt $DaysAgo } # get latest file if none meet our criteria if ((Test-Path $path) -and (-not $files) ) { $newestFile = Get-ChildItem $path |Sort-Object LastAccessTime -Descending | Select-Object -First 1 $files += $newestFile } $files } if (Test-Path HKLM:\SOFTWARE\Microsoft\CCM\Logging\@Global) { $ccmFolder = (Get-ItemProperty HKLM:\SOFTWARE\Microsoft\CCM\Logging\@Global).LogDirectory $copyPath = "$env:temp\CollectedData\Intune\Files\ConfigMgr" if ($ccmFolder) { if (-not(test-path $copyPath) ) { $x = mkdir $copyPath -Force } $filesToCollect = Get-FilesOlderThan -path $ccmFolder -days 3 foreach ($fileToCollect in $filesToCollect) { copy $fileToCollect.PSPath $copyPath} } } else { "CCM folder not found. Exiting." } function RunCommand { Param ([string]$cmdToRun) echo "`r`n===========================================`r`n`t`t $cmdToRun `r`n===========================================`r`n" try { Invoke-Expression($cmdToRun) -ErrorAction Stop } catch { $error[0].ToString()} } RunCommand -cmdToRun "certutil -v -template" if (Test-Path HKLM:\SOFTWARE\Microsoft\Cryptography\MSCEP\CAInfo) { $config = (Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Cryptography\MSCEP\CAInfo).Configuration RunCommand -cmdToRun "certutil -CATemplates -config $config" } <# .SYNOPSIS Highlights configuration problems on an NDES server, as configured for use with Intune Standalone SCEP certificates. .DESCRIPTION Validate-NDESConfig looks at the configuration of your NDES server and ensures it aligns to the "Configure and manage SCEP certificates with Intune" article. Note: This script is forked and modified to run unattended in One Data Collector .NOTE This script is used purely to validate the configuration. All remedial tasks will need to be carried out manually. Where possible, a link and section description will be provided. .EXAMPLE .\Validate-NDESConfiguration -NDESServiceAccount Contoso\NDES_SVC.com -IssuingCAServerFQDN IssuingCA.contoso.com -SCEPUserCertTemplate SCEPGeneral .EXAMPLE .\Validate-NDESConfiguration -help .LINK https://docs.microsoft.com/en-us/intune/certificates-scep-configure#configure-your-infrastructure #> [CmdletBinding(DefaultParameterSetName="Unattended")] Param( [parameter(ParameterSetName="Unattended")] [alias("ua","silent","s","unattended")] [switch]$unattend = $true, [parameter(Mandatory=$false,ParameterSetName="NormalRun")] [alias("sa")] [ValidateScript({ if (-not ($unattend) -and ($_ -match ".\\.") ) { $True } else { Write-Output "Please use the format Domain\Username for the NDES Service Account variable." } $EnteredDomain = $_.split("\") $ads = New-Object -ComObject ADSystemInfo try { $Domain = $ads.GetType().InvokeMember('DomainShortName','GetProperty', $Null, $ads, $Null) if ($EnteredDomain -like "$Domain") { $True } else { if (-not $unattend) { Write-Output "Incorrect Domain. Ensure domain is '$($Domain)\<USERNAME>'" } } } catch { "Unable to query domain. Verify that server is domain joined" } } )] [string]$NDESServiceAccount, [parameter(Mandatory=$false,ParameterSetName="NormalRun")] [alias("ca")] [ValidateScript({ $Domain = (Get-WmiObject Win32_ComputerSystem).domain if ($_ -match $Domain) { $True } else { Write-Output "The Network Device Enrollment Server and the Certificate Authority are not members of the same Active Directory domain. This is an unsupported configuration." } } )] [string]$IssuingCAServerFQDN, [parameter(Mandatory=$false,ParameterSetName="NormalRun")] [alias("t")] [string]$SCEPUserCertTemplate, [parameter(ParameterSetName="Help")] [alias("h","?","/?")] [switch]$help, [parameter(ParameterSetName="Help")] [alias("u")] [switch]$usage ) ####################################################################### Function Log-ScriptEvent { [CmdletBinding()] Param( [parameter(Mandatory=$True)] [String]$LogFilePath = "$env:temp\CollectedData\Intune\Commands\NDES", [parameter(Mandatory=$True)] [String]$Value, [parameter(Mandatory=$True)] [String]$Component, [parameter(Mandatory=$True)] [ValidateRange(1,3)] [Single]$Severity = 3 ) $DateTime = New-Object -ComObject WbemScripting.SWbemDateTime $DateTime.SetVarDate($(Get-Date)) $UtcValue = $DateTime.Value $UtcOffset = $UtcValue.Substring(21, $UtcValue.Length - 21) $prettyLogFileName = $LogFilePath -replace "\.log$", "-pretty.log" $LogLine = "<![LOG[$Value]LOG]!>" +` "<time=`"$(Get-Date -Format HH:mm:ss.fff)$($UtcOffset)`" " +` "date=`"$(Get-Date -Format M-d-yyyy)`" " +` "component=`"$Component`" " +` "context=`"$([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)`" " +` "type=`"$Severity`" " +` "thread=`"$([Threading.Thread]::CurrentThread.ManagedThreadId)`" " +` "file=`"`">" $PrettyLogLine = "$(Get-Date -Format MM-dd-yyyy) $(Get-Date -Format HH:mm:ss.fff)$($UtcOffset)" +` "[$Component] " +` "[$([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)] " + "[Severity = $Severity] $Value" Add-Content -Path $prettyLogFileName -Value $PrettyLogLine Add-Content -Path $LogFilePath -Value $LogLine } ########################################################################################################## function Show-Usage { Write-Output "" Write-Output "-help -h Displays the help." Write-Output "-usage -u Displays this usage information." Write-Output "-NDESExternalHostname -ed External DNS name for the NDES server (SSL certificate subject will be checked for this. It should be in the SAN of the certificate if" Write-Output " clients communicate directly with the NDES server)" Write-Output "-NDESServiceAccount -sa Username of the NDES service account. Format is Domain\sAMAccountName, such as Contoso\NDES_SVC." Write-Output "-IssuingCAServerFQDN -ca Name of the issuing CA to which you'll be connecting the NDES server. Format is FQDN, such as 'MyIssuingCAServer.contoso.com'." Write-Output "-SCEPUserCertTemplate -t Name of the SCEP Certificate template. Please note this is _not_ the display name of the template. Value should not contain spaces." Write-Output "" } ####################################################################### function Get-NDESHelp { Write-Output "" Write-Output "Verifies if the NDES server meets all the required configuration. " Write-Output "" Write-Output "The NDES server role is required as back-end infrastructure for Intune Standalone for delivering VPN and Wi-Fi certificates via the SCEP protocol to mobile devices and desktop clients." Write-Output "See https://docs.microsoft.com/en-us/intune/certificates-scep-configure." Write-Output "" } ####################################################################### if ($help){ Get-NDESHelp break } if ($usage){ Show-Usage break } ####################################################################### #Requires -version 3.0 #Requires -RunAsAdministrator ####################################################################### if (Get-Service NDESConnectorSvc -ErrorAction SilentlyContinue ) { $parent = [System.IO.Path]::GetTempPath() [string] $name = [System.Guid]::NewGuid() New-Item -ItemType Directory -Path (Join-Path $parent $name) | Out-Null $TempDirPath = "$parent$name" $LogFilePath = "$($TempDirPath)\Validate-NDESConfig.log" $nil = Import-Module WebAdministration -Force $unattend = $true # create path for logging $outputPath = "$env:temp\CollectedData\Intune\Commands\NDES" $nil = if (-not (Test-Path $outputPath)) { mkdir $outputPath -Force} $WriteLogOutputPath = $true $error.Clear() ####################################################################### #region Proceed with Variables... if ($unattend) { $NDESServiceAccount = Get-Item 'IIS:\AppPools\SCEP' | select -expandproperty processmodel | select -Expand username $IssuingCAServerFQDN = (Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Cryptography\MSCEP\CAInfo).Configuration -replace "\\.*$", "" $SCEPUserCertTemplate = (Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Cryptography\MSCEP).EncryptionTemplate $confirmation = "y" } else { Write-Output "" Write-Output "......................................................." Write-Output "" Write-Output "NDES Service Account = $($NDESServiceAccount)" Write-Output "" Write-Output "Issuing CA Server = $($IssuingCAServerFQDN)" Write-Output "" Write-Output "SCEP Certificate Template = $($SCEPUserCertTemplate)" Write-Output "" Write-Output "......................................................." Write-Output "" Write-Output "Proceed with variables? [Y]es, [N]o" $confirmation = Read-Host } #endregion ####################################################################### if ($confirmation -eq 'y'){ Write-Output "" Write-Output "......................................................." Log-ScriptEvent $LogFilePath "Initializing log file $($TempDirPath)\Validate-NDESConfig.log" NDES_Validation 1 Log-ScriptEvent $LogFilePath "Proceeding with variables=YES" NDES_Validation 1 Log-ScriptEvent $LogFilePath "NDESServiceAccount=$($NDESServiceAccount)" NDES_Validation 1 Log-ScriptEvent $LogFilePath "IssuingCAServer=$($IssuingCAServerFQDN)" NDES_Validation 1 Log-ScriptEvent $LogFilePath "SCEPCertificateTemplate=$($SCEPUserCertTemplate)" NDES_Validation 1 ####################################################################### #region Install RSAT tools, Check if NDES and IIS installed if (-not (Get-WindowsFeature ADCS-Device-Enrollment).Installed){ Write-Output "Error: NDES Not installed" Write-Output "Exiting....................." Log-ScriptEvent $LogFilePath "NDES Not installed" NDES_Validation 3 break } Install-WindowsFeature RSAT-AD-PowerShell | Out-Null Import-Module ActiveDirectory | Out-Null if (-not (Get-WindowsFeature Web-WebServer).Installed){ $IISNotInstalled = $TRUE Write-Output "Warning: IIS is not installed. Some tests will not run as we're unable to import the WebAdministration module" Write-Output "" Log-ScriptEvent $LogFilePath "IIS is not installed. Some tests will not run as we're unable to import the WebAdministration module" NDES_Validation 2 } else { Import-Module WebAdministration | Out-Null } #endregion ####################################################################### #region checking OS version Write-Output "" Write-Output "Checking Windows OS version..." Write-Output "" Log-ScriptEvent $LogFilePath "Checking OS Version" NDES_Validation 1 $OSVersion = (Get-CimInstance -class Win32_OperatingSystem).Version $MinOSVersion = "6.3" if ([version]$OSVersion -lt [version]$MinOSVersion){ Write-Output "Error: Unsupported OS Version. NDES Requires 2012 R2 and above." Log-ScriptEvent $LogFilePath "Unsupported OS Version. NDES Requires 2012 R2 and above." NDES_Validation 3 } else { Write-Output "Success: OS Version $($OSVersion) supported." Log-ScriptEvent $LogFilePath "Server is version $($OSVersion)" NDES_Validation 1 } #endregion ####################################################################### #region Checking NDES Service Account properties in Active Directory Write-Output "" Write-Output "......................................................." Write-Output "" Write-Output "Checking NDES Service Account properties in Active Directory..." Write-Output "" Log-ScriptEvent $LogFilePath "Checking NDES Service Account properties in Active Directory" NDES_Validation 1 $ADUser = $NDESServiceAccount.split("\")[1] try { $ADUserProps = (Get-ADUser $ADUser -Properties SamAccountName,enabled,AccountExpirationDate,accountExpires,accountlockouttime,PasswordExpired,PasswordLastSet,PasswordNeverExpires,LockedOut) } catch { Log-ScriptEvent $LogFilePath "Error looking up AD User:`r`n`r`n$error" NDES_Validation 3 } if ($ADUserProps.enabled -ne $TRUE -OR $ADUserProps.PasswordExpired -ne $false -OR $ADUserProps.LockedOut -eq $TRUE){ Write-Output "Error: Problem with the AD account. Please see output below to determine the issue" Write-Output "" Log-ScriptEvent $LogFilePath "Problem with the AD account. Please see output below to determine the issue" NDES_Validation 3 } else { Write-Output "Success: NDES Service Account seems to be in working order:" Log-ScriptEvent $LogFilePath "NDES Service Account seems to be in working order" NDES_Validation 1 } try { Get-ADUser $ADUser -Properties SamAccountName,enabled,AccountExpirationDate,accountExpires,accountlockouttime,PasswordExpired,PasswordLastSet,PasswordNeverExpires,LockedOut | fl SamAccountName,enabled,AccountExpirationDate,accountExpires,accountlockouttime,PasswordExpired,PasswordLastSet,PasswordNeverExpires,LockedOut } catch { Log-ScriptEvent $LogFilePath "Error looking up AD User:`r`n`r`n$error" NDES_Validation 3 } #endregion ####################################################################### #region Checking if NDES server is the CA Write-Output "`n.......................................................`n" Write-Output "Checking if NDES server is the CA...`n" Log-ScriptEvent $LogFilePath "Checking if NDES server is the CA" NDES_Validation 1 $hostname = ([System.Net.Dns]::GetHostByName(($env:computerName))).hostname $CARoleInstalled = (Get-WindowsFeature ADCS-Cert-Authority).InstallState -eq "Installed" if ($hostname -match $IssuingCAServerFQDN){ Write-Output "Error: NDES is running on the CA. This is an unsupported configuration!" Log-ScriptEvent $LogFilePath "NDES is running on the CA" NDES_Validation 3 } elseif($CARoleInstalled) { Write-Output "Error: NDES server has Certification Authority Role installed. This is an unsupported configuration!" Log-ScriptEvent $LogFilePath "NDES server has Certification Authority Role installed" NDES_Validation 3 } else { Write-Output "Success: NDES server is not running on the CA" Log-ScriptEvent $LogFilePath "NDES server is not running on the CA" NDES_Validation 1 } #endregion ####################################################################### #region Checking NDES Service Account local permissions Write-Output "" Write-Output "......................................................." Write-Output "" Write-Output "Checking NDES Service Account local permissions..." Write-Output "" Log-ScriptEvent $LogFilePath "Checking NDES Service Account local permissions" NDES_Validation 1 if ((net localgroup) -match "Administrators"){ $LocalAdminsMember = ((net localgroup Administrators)) if ($LocalAdminsMember -like "*$NDESServiceAccount*"){ Write-Output "Warning: NDES Service Account is a member of the local Administrators group. This will provide the requisite rights but is _not_ a secure configuration. Use IIS_IUSERS instead." Log-ScriptEvent $LogFilePath "NDES Service Account is a member of the local Administrators group. This will provide the requisite rights but is _not_ a secure configuration. Use IIS_IUSERS instead." NDES_Validation 2 } else { Write-Output "Success: NDES Service account is not a member of the Local Administrators group" Log-ScriptEvent $LogFilePath "NDES Service account is not a member of the Local Administrators group" NDES_Validation 1 } Write-Output "" Write-Output "Checking NDES Service account is a member of the IIS_IUSR group..." Write-Output "" if ((net localgroup) -match "IIS_IUSRS"){ $IIS_IUSRMembers = ((net localgroup IIS_IUSRS)) if ($IIS_IUSRMembers -like "*$NDESServiceAccount*"){ Write-Output "Success: NDES Service Account is a member of the local IIS_IUSR group" Log-ScriptEvent $LogFilePath "NDES Service Account is a member of the local IIS_IUSR group" NDES_Validation 1 } else { Write-Output "Error: NDES Service Account is not a member of the local IIS_IUSR group" Log-ScriptEvent $LogFilePath "NDES Service Account is not a member of the local IIS_IUSR group" NDES_Validation 3 Write-Output "" Write-Output "Checking Local Security Policy for explicit rights via gpedit..." Write-Output "" $TempFile = [System.IO.Path]::GetTempFileName() & "secedit" "/export" "/cfg" "$TempFile" | Out-Null $LocalSecPol = Get-Content $TempFile try { $ADUserProps = Get-ADUser $ADUser $NDESSVCAccountSID = $ADUserProps.SID.Value $LocalSecPolResults = $LocalSecPol | Select-String $NDESSVCAccountSID } catch { Log-ScriptEvent $LogFilePath "Error looking up AD User:`r`n`r`n$error" NDES_Validation 3 } if ($LocalSecPolResults -match "SeInteractiveLogonRight" -AND $LocalSecPolResults -match "SeBatchLogonRight" -AND $LocalSecPolResults -match "SeServiceLogonRight"){ Write-Output "Success: NDES Service Account has been assigned the Logon Locally, Logon as a Service and Logon as a batch job rights explicitly." Log-ScriptEvent $LogFilePath "NDES Service Account has been assigned the Logon Locally, Logon as a Service and Logon as a batch job rights explicitly." NDES_Validation 1 Write-Output "" Write-Output "Note:" Write-Output " The Logon Locally is not required in normal runtime." Write-Output "" Write-Output "Note:" Write-Output 'Consider using the IIS_IUSERS group instead of explicit rights as documented under "Step 1 - Create an NDES service account".' Write-Output "URL: https://docs.microsoft.com/en-us/intune/certificates-scep-configure#configure-your-infrastructure" } else { Write-Output "Error: NDES Service Account has _NOT_ been assigned the Logon Locally, Logon as a Service or Logon as a batch job rights _explicitly_." Write-Output 'Please review "Step 1 - Create an NDES service account".' Write-Output "https://docs.microsoft.com/en-us/intune/certificates-scep-configure#configure-your-infrastructure" Log-ScriptEvent $LogFilePath "NDES Service Account has _NOT_ been assigned the Logon Locally, Logon as a Service or Logon as a batch job rights _explicitly_." NDES_Validation 3 } } } else { Write-Output "Error: No IIS_IUSRS group exists. Ensure IIS is installed." Write-Output 'Please review `"Step 3.1 - Configure prerequisites on the NDES server`".' Write-Output "https://docs.microsoft.com/en-us/intune/certificates-scep-configure#configure-your-infrastructure" Log-ScriptEvent $LogFilePath "No IIS_IUSRS group exists. Ensure IIS is installed." NDES_Validation 3 } } else { Write-Output "Warning: No local Administrators group exists, likely due to this being a Domain Controller. It is not recommended to run NDES on a Domain Controller." Log-ScriptEvent $LogFilePath "No local Administrators group exists, likely due to this being a Domain Controller. It is not recommended to run NDES on a Domain Controller." NDES_Validation 2 } #endregion ####################################################################### #region Checking Windows Features are installed. Write-Output "" Write-Output "" Write-Output "......................................................." Write-Output "" Write-Output "Checking Windows Features are installed..." Write-Output "" Log-ScriptEvent $LogFilePath "Checking Windows Features are installed..." NDES_Validation 1 $WindowsFeatures = @("Web-Filtering","Web-Net-Ext45","NET-Framework-45-Core","NET-WCF-HTTP-Activation45","Web-Metabase","Web-WMI") foreach($WindowsFeature in $WindowsFeatures){ $Feature = Get-WindowsFeature $WindowsFeature $FeatureDisplayName = $Feature.displayName if($Feature.installed){ Write-Output "Success:$FeatureDisplayName Feature Installed" Log-ScriptEvent $LogFilePath "$($FeatureDisplayName) Feature Installed" NDES_Validation 1 } else { Write-Output "Error: $FeatureDisplayName Feature not installed!" Write-Output 'Please review "Step 3.1b - Configure prerequisites on the NDES server".' Write-Output "URL: https://docs.microsoft.com/en-us/intune/certificates-scep-configure#configure-your-infrastructure" Log-ScriptEvent $LogFilePath "$($FeatureDisplayName) Feature not installed" NDES_Validation 3 } } #endregion ################################################################# #region Checking NDES Install Paramaters $ErrorActionPreference = "SilentlyContinue" Write-Output "" Write-Output "......................................................." Write-Output "" Write-Output "Checking NDES Install Paramaters..." Write-Output "" Log-ScriptEvent $LogFilePath "Checking NDES Install Paramaters" NDES_Validation 1 $InstallParams = @(Get-WinEvent -LogName "Microsoft-Windows-CertificateServices-Deployment/Operational" | Where-Object {$_.id -eq "105"}| Where-Object {$_.message -match "Install-AdcsNetworkDeviceEnrollmentService"}| Sort-Object -Property TimeCreated -Descending | Select-Object -First 1) if ($InstallParams.Message -match '-SigningProviderName "Microsoft Strong Cryptographic Provider"' -AND ($InstallParams.Message -match '-EncryptionProviderName "Microsoft Strong Cryptographic Provider"')) { Write-Output "Success: Correct CSP used in install parameters" Write-Output "" Write-Output $InstallParams.Message Log-ScriptEvent $LogFilePath "Correct CSP used in install parameters:" NDES_Validation 1 Log-ScriptEvent $LogFilePath "$($InstallParams.Message)" NDES_Eventvwr 1 } else { Write-Output "Error: Incorrect CSP selected during install. NDES only supports the CryptoAPI CSP." Write-Output "" Write-Output $InstallParams.Message Log-ScriptEvent $LogFilePath "Error: Incorrect CSP selected during install. NDES only supports the CryptoAPI CSP" NDES_Validation 3 Log-ScriptEvent $LogFilePath "$($InstallParams.Message)" NDES_Eventvwr 3 } $ErrorActionPreference = "Continue" #endregion ################################################################# #region Checking IIS Application Pool health Write-Output "" Write-Output "......................................................." Write-Output "" Write-Output "Checking IIS Application Pool health..." Write-Output "" Log-ScriptEvent $LogFilePath "Checking IIS Application Pool health" NDES_Validation 1 if (-not ($IISNotInstalled -eq $TRUE)){ # If SCEP AppPool Exists if (Test-Path 'IIS:\AppPools\SCEP'){ $IISSCEPAppPoolAccount = (Get-Item 'IIS:\AppPools\SCEP' -ErrorAction SilentlyContinue | select -ExpandProperty processmodel).username if ((Get-WebAppPoolState "SCEP").value -match "Started"){ $SCEPAppPoolRunning = $TRUE } } else { Write-Output "Error: SCEP Application Pool missing!" Write-Output 'Please review "Step 3.1 - Configure prerequisites on the NDES server"'. Write-Output "URL: https://docs.microsoft.com/en-us/intune/certificates-scep-configure#configure-your-infrastructure" Log-ScriptEvent $LogFilePath "SCEP Application Pool missing" NDES_Validation 3 } if ($IISSCEPAppPoolAccount -contains "$NDESServiceAccount"){ Write-Output "Success: Application Pool is configured to use $($IISSCEPAppPoolAccount)" Log-ScriptEvent $LogFilePath "Application Pool is configured to use $($IISSCEPAppPoolAccount)" NDES_Validation 1 } else { Write-Output "Error: Application Pool is not configured to use the NDES Service Account" Write-Output 'Please review "Step 4.1 - Configure NDES for use with Intune".' Write-Output "URL: https://docs.microsoft.com/en-us/intune/certificates-scep-configure#configure-your-infrastructure" Log-ScriptEvent $LogFilePath "Application Pool is not configured to use the NDES Service Account" NDES_Validation 3 } if ($SCEPAppPoolRunning){ Write-Output "Success: SCEP Application Pool is Started " Log-ScriptEvent $LogFilePath "SCEP Application Pool is Started" NDES_Validation 1 } else { Write-Output "Error: SCEP Application Pool is stopped!" Write-Output "Please start the SCEP Application Pool via IIS Management Console. You should also review the Application Event log output for Errors" Log-ScriptEvent $LogFilePath "SCEP Application Pool is stopped" NDES_Validation 3 } } else { Write-Output "IIS is not installed." Log-ScriptEvent $LogFilePath "SCEP Application Pool is stopped" NDES_Validation 3 } #endregion ################################################################# #region Checking Request Filtering Write-Output "" Write-Output "" Write-Output "......................................................." Write-Output "" Write-Output "Checking Request Filtering (Default Web Site -> Request Filtering -> Edit Feature Setting) has been configured in IIS..." Write-Output "" Log-ScriptEvent $LogFilePath "Checking Request Filtering" NDES_Validation 1 if (-not ($IISNotInstalled -eq $TRUE)){ [xml]$RequestFiltering = (c:\windows\system32\inetsrv\appcmd.exe list config "default web site" /section:requestfiltering) if ($RequestFiltering.'system.webserver'.security.requestFiltering.requestLimits.maxQueryString -eq "65534"){ Write-Output "Success: MaxQueryString Set Correctly" Log-ScriptEvent $LogFilePath "MaxQueryString Set Correctly" NDES_Validation 1 } else { Write-Output "MaxQueryString not set correctly!" Write-Output 'Please review "Step 4.4 - Configure NDES for use with Intune".' Write-Output "URL: https://docs.microsoft.com/en-us/intune/certificates-scep-configure#configure-your-infrastructure" Log-ScriptEvent $LogFilePath "MaxQueryString not set correctly" NDES_Validation 3 } if ($RequestFiltering.'system.webserver'.security.requestFiltering.requestLimits.maxUrl -eq "65534"){ Write-Output "Success: MaxUrl Set Correctly" Log-ScriptEvent $LogFilePath "MaxUrl Set Correctly" NDES_Validation 1 } else { Write-Output "maxUrl not set correctly!" Write-Output 'Please review "Step 4.4 - Configure NDES for use with Intune".' Write-Output "URL: https://docs.microsoft.com/en-us/intune/certificates-scep-configure#configure-your-infrastructure'" Log-ScriptEvent $LogFilePath "maxUrl not set correctly" NDES_Validation 3 } } else { Write-Output "IIS is not installed." Log-ScriptEvent $LogFilePath "IIS is not installed" NDES_Validation 3 } #endregion ################################################################# #region Checking registry has been set to allow long URLs Write-Output "" Write-Output "......................................................." Write-Output "" Write-Output 'Checking registry "HKLM:SYSTEM\CurrentControlSet\Services\HTTP\Parameters" has been set to allow long URLs...' Write-Output "" Log-ScriptEvent $LogFilePath "Checking registry (HKLM:SYSTEM\CurrentControlSet\Services\HTTP\Parameters) has been set to allow long URLs" NDES_Validation 1 if (-not ($IISNotInstalled -eq $TRUE)){ If ((Get-ItemProperty -Path HKLM:SYSTEM\CurrentControlSet\Services\HTTP\Parameters -Name MaxFieldLength).MaxfieldLength -notmatch "65534"){ Write-Output "Error: MaxFieldLength not set to 65534 in the registry!" Write-Output "" Write-Output 'Please review "Step 4.3 - Configure NDES for use with Intune".' Write-Output "URL: https://docs.microsoft.com/en-us/intune/certificates-scep-configure#configure-your-infrastructure" Log-ScriptEvent $LogFilePath "MaxFieldLength not set to 65534 in the registry" NDES_Validation 3 } else { Write-Output "Success: MaxFieldLength set correctly" Log-ScriptEvent $LogFilePath "MaxFieldLength set correctly" NDES_Validation 1 } if ((Get-ItemProperty -Path HKLM:SYSTEM\CurrentControlSet\Services\HTTP\Parameters -Name MaxRequestBytes).MaxRequestBytes -notmatch "65534"){ Write-Output "MaxRequestBytes not set to 65534 in the registry!" Write-Output "" Write-Output 'Please review "Step 4.3 - Configure NDES for use with Intune".' Write-Output "URL: https://docs.microsoft.com/en-us/intune/certificates-scep-configure#configure-your-infrastructure'" Log-ScriptEvent $LogFilePath "MaxRequestBytes not set to 65534 in the registry" NDES_Validation 3 } else { Write-Output "Success: MaxRequestBytes set correctly" Log-ScriptEvent $LogFilePath "MaxRequestBytes set correctly" NDES_Validation 1 } } else { Write-Output "IIS is not installed." Log-ScriptEvent $LogFilePath "IIS is not installed." NDES_Validation 3 } #endregion ################################################################# #region Checking SPN has been set... Write-Output "" Write-Output "......................................................." Write-Output "" Write-Output "Checking SPN has been set..." Write-Output "" Log-ScriptEvent $LogFilePath "Checking SPN has been set" NDES_Validation 1 $hostname = ([System.Net.Dns]::GetHostByName(($env:computerName))).hostname try { $spn = setspn.exe -L $ADUser 2>>$LogFilePath } catch { Log-ScriptEvent $LogFilePath "Error looking up SPNs:`r`n`r`n$error" NDES_Validation 3 } if ($spn -match $hostname){ Write-Output "Success: Correct SPN set for the NDES service account:" Write-Output "" Write-Output $spn Log-ScriptEvent $LogFilePath "Correct SPN set for the NDES service account: $($spn)" NDES_Validation 1 } else { Write-Output "Error: Missing or Incorrect SPN set for the NDES Service Account!" Write-Output 'Please review "Step 3.1c - Configure prerequisites on the NDES server".' Write-Output "URL: https://docs.microsoft.com/en-us/intune/certificates-scep-configure#configure-your-infrastructure" Log-ScriptEvent $LogFilePath "Missing or Incorrect SPN set for the NDES Service Account" NDES_Validation 3 } #endregion ################################################################# #region Checking there are no intermediate certs are in the Trusted Root store Write-Output "" Write-Output "......................................................." Write-Output "" Write-Output "Checking there are no intermediate certs are in the Trusted Root store..." Write-Output "" Log-ScriptEvent $LogFilePath "Checking there are no intermediate certs are in the Trusted Root store" NDES_Validation 1 $IntermediateCertCheck = Get-Childitem cert:\LocalMachine\root -Recurse | Where-Object {$_.Issuer -ne $_.Subject} if ($IntermediateCertCheck){ Write-Output "Error: Intermediate certificate found in the Trusted Root store. This can cause undesired effects and should be removed." Write-Output "Certificates:" Write-Output "" Write-Output $IntermediateCertCheck Log-ScriptEvent $LogFilePath "Intermediate certificate found in the Trusted Root store: $($IntermediateCertCheck)" NDES_Validation 3 } else { Write-Output "Success: Trusted Root store does not contain any Intermediate certificates." Log-ScriptEvent $LogFilePath "Trusted Root store does not contain any Intermediate certificates." NDES_Validation 1 } #endregion ################################################################# #region Checking the EnrollmentAgentOffline and CEPEncryption are present $ErrorActionPreference = "Silentlycontinue" Write-Output "" Write-Output "......................................................." Write-Output "" Write-Output "Checking the EnrollmentAgentOffline and CEPEncryption are present..." Write-Output "" Log-ScriptEvent $LogFilePath "Checking the EnrollmentAgentOffline and CEPEncryption are present" NDES_Validation 1 $certs = Get-ChildItem cert:\LocalMachine\My\ # Looping through all certificates in LocalMachine Store Foreach ($item in $certs){ $Output = ($item.Extensions| where-object {$_.oid.FriendlyName -like "**"}).format(0).split(",") if ($Output -match "EnrollmentAgentOffline"){ $EnrollmentAgentOffline = $TRUE } if ($Output -match "CEPEncryption"){ $CEPEncryption = $TRUE } } # Checking if EnrollmentAgentOffline certificate is present if ($EnrollmentAgentOffline){ Write-Output "Success: EnrollmentAgentOffline certificate is present" Log-ScriptEvent $LogFilePath "EnrollmentAgentOffline certificate is present" NDES_Validation 1 } else { Write-Output "Error: EnrollmentAgentOffline certificate is not present!" Write-Output "This can take place when an account without Enterprise Admin permissions installs NDES. You may need to remove the NDES role and reinstall with the correct permissions." Write-Output 'Please review "Step 3.1 - Configure prerequisites on the NDES server".' Write-Output "URL: https://docs.microsoft.com/en-us/intune/certificates-scep-configure#configure-your-infrastructure" Log-ScriptEvent $LogFilePath "EnrollmentAgentOffline certificate is not present" NDES_Validation 3 } # Checking if CEPEncryption is present if ($CEPEncryption){ Write-Output "Success: CEPEncryption certificate is present" Log-ScriptEvent $LogFilePath "CEPEncryption certificate is present" NDES_Validation 1 } else { Write-Output "Error: CEPEncryption certificate is not present!" Write-Output "This can take place when an account without Enterprise Admin permissions installs NDES. You may need to remove the NDES role and reinstall with the correct permissions." Write-Output 'Please review "Step 3.1 - Configure prerequisites on the NDES server".' Write-Output "URL: https://docs.microsoft.com/en-us/intune/certificates-scep-configure#configure-your-infrastructure" Log-ScriptEvent $LogFilePath "CEPEncryption certificate is not present" NDES_Validation 3 } $ErrorActionPreference = "Continue" #endregion ################################################################# #region Checking registry has been set with the SCEP certificate template name Write-Output "" Write-Output "......................................................." Write-Output "" Write-Output 'Checking registry "HKLM:SOFTWARE\Microsoft\Cryptography\MSCEP" has been set with the SCEP certificate template name...' Write-Output "" Log-ScriptEvent $LogFilePath "Checking registry (HKLM:SOFTWARE\Microsoft\Cryptography\MSCEP) has been set with the SCEP certificate template name" NDES_Validation 1 if (-not (Test-Path HKLM:SOFTWARE\Microsoft\Cryptography\MSCEP)){ Write-Output "Error: Registry key does not exist. This can occur if the NDES role has been installed but not configured." Write-Output 'Please review "Step 3 - Configure prerequisites on the NDES server".' Write-Output "URL: https://docs.microsoft.com/en-us/intune/certificates-scep-configure#configure-your-infrastructure" Log-ScriptEvent $LogFilePath "MSCEP Registry key does not exist." NDES_Validation 3 } else { $SignatureTemplate = (Get-ItemProperty -Path HKLM:SOFTWARE\Microsoft\Cryptography\MSCEP\ -Name SignatureTemplate).SignatureTemplate $EncryptionTemplate = (Get-ItemProperty -Path HKLM:SOFTWARE\Microsoft\Cryptography\MSCEP\ -Name EncryptionTemplate).EncryptionTemplate $GeneralPurposeTemplate = (Get-ItemProperty -Path HKLM:SOFTWARE\Microsoft\Cryptography\MSCEP\ -Name GeneralPurposeTemplate).GeneralPurposeTemplate $DefaultUsageTemplate = "IPSECIntermediateOffline" if ($SignatureTemplate -match $DefaultUsageTemplate -AND $EncryptionTemplate -match $DefaultUsageTemplate -AND $GeneralPurposeTemplate -match $DefaultUsageTemplate){ Write-Output "Error: Registry has not been configured with the SCEP Certificate template name. Default values have _not_ been changed." Write-Output 'Please review "Step 3.1 - Configure prerequisites on the NDES server".' Write-Output "URL: https://docs.microsoft.com/en-us/intune/certificates-scep-configure#configure-your-infrastructure" Write-Output "" Log-ScriptEvent $LogFilePath "Registry has not been configured with the SCEP Certificate template name. Default values have _not_ been changed." NDES_Validation 3 $FurtherReading = $FALSE } else { Write-Output "One or more default values have been changed." Write-Output "" Write-Output "Checking SignatureTemplate key..." Write-Output "" if ($SignatureTemplate -match $SCEPUserCertTemplate){ Write-Output "Success: SCEP certificate template '$($SCEPUserCertTemplate)' has been written to the registry under the _SignatureTemplate_ key. Ensure this aligns with the usage specificed on the SCEP template." Write-Output "" Log-ScriptEvent $LogFilePath "SCEP certificate template $($SCEPUserCertTemplate)' has been written to the registry under the _SignatureTemplate_ key" NDES_Validation 1 } else { Write-Output '"SignatureTemplate key does not match the SCEP certificate template name. Unless your template is explicitly set for the "Signature" purpose, this can safely be ignored."' Write-Output "" Write-Output "Registry value: $($SignatureTemplate)" Write-Output "" Write-Output "SCEP certificate template value: $($SCEPUserCertTemplate)" Write-Output "" Log-ScriptEvent $LogFilePath "SignatureTemplate key does not match the SCEP certificate template name.Registry value=$($SignatureTemplate)|SCEP certificate template value=$($SCEPUserCertTemplate)" NDES_Validation 2 } Write-Output "......................." Write-Output "" Write-Output "Checking EncryptionTemplate key..." Write-Output "" if ($EncryptionTemplate -match $SCEPUserCertTemplate){ Write-Output "Success: SCEP certificate template '$($SCEPUserCertTemplate)' has been written to the registry under the _EncryptionTemplate_ key. Ensure this aligns with the usage specificed on the SCEP template." Write-Output "" Log-ScriptEvent $LogFilePath "SCEP certificate template $($SCEPUserCertTemplate) has been written to the registry under the _EncryptionTemplate_ key" NDES_Validation 1 } else { Write-Output '"EncryptionTemplate key does not match the SCEP certificate template name. Unless your template is explicitly set for the "Encryption" purpose, this can safely be ignored."' Write-Output "" Write-Output "Registry value: $($EncryptionTemplate)" Write-Output "" Write-Output "SCEP certificate template value: $($SCEPUserCertTemplate)" Write-Output "" Log-ScriptEvent $LogFilePath "EncryptionTemplate key does not match the SCEP certificate template name.Registry value=$($EncryptionTemplate)|SCEP certificate template value=$($SCEPUserCertTemplate)" NDES_Validation 2 } Write-Output "......................." Write-Output "" Write-Output "Checking GeneralPurposeTemplate key..." Write-Output "" if ($GeneralPurposeTemplate -match $SCEPUserCertTemplate){ Write-Output "Success: SCEP certificate template '$($SCEPUserCertTemplate)' has been written to the registry under the _GeneralPurposeTemplate_ key. Ensure this aligns with the usage specificed on the SCEP template" Log-ScriptEvent $LogFilePath "SCEP certificate template $($SCEPUserCertTemplate) has been written to the registry under the _GeneralPurposeTemplate_ key" NDES_Validation 1 } else { Write-Output '"GeneralPurposeTemplate key does not match the SCEP certificate template name. Unless your template is set for the "Signature and Encryption" (General) purpose, this can safely be ignored."' Write-Output "" Write-Output "Registry value: $($GeneralPurposeTemplate)" Write-Output "" Write-Output "SCEP certificate template value: $($SCEPUserCertTemplate)" Write-Output "" Log-ScriptEvent $LogFilePath "GeneralPurposeTemplate key does not match the SCEP certificate template name.Registry value=$($GeneralPurposeTemplate)|SCEP certificate template value=$($SCEPUserCertTemplate)" NDES_Validation 2 } } if ($furtherreading-EQ $true){ Write-Output "......................." Write-Output "" Write-Output 'For further reading, please review "Step 4.2 - Configure NDES for use with Intune".' Write-Output "URL: https://docs.microsoft.com/en-us/intune/certificates-scep-configure#configure-your-infrastructure" } } $ErrorActionPreference = "Continue" #endregion ################################################################# #region Checking server certificate. Write-Output "" Write-Output "......................................................." Write-Output "" Write-Output "Checking IIS SSL certificate is valid for use..." Write-Output "" Log-ScriptEvent $LogFilePath "Checking IIS SSL certificate is valid for use" NDES_Validation 1 $hostname = ([System.Net.Dns]::GetHostByName(($env:computerName))).hostname $serverAuthEKU = "1.3.6.1.5.5.7.3.1" # Server Authentication $allSSLCerts = Get-ChildItem Cert:\LocalMachine\My $BoundServerCert = netsh http show sslcert foreach ($Cert in $allSSLCerts) { $ServerCertThumb = $cert.Thumbprint if ($BoundServerCert -match $ServerCertThumb){ $BoundServerCertThumb = $ServerCertThumb } } $ServerCertObject = Get-ChildItem Cert:\LocalMachine\My\$BoundServerCertThumb if ($ServerCertObject.Issuer -match $ServerCertObject.Subject){ $SelfSigned = $true } else { $SelfSigned = $false } if ($ServerCertObject.EnhancedKeyUsageList -match $serverAuthEKU -AND (($ServerCertObject.Subject -match $hostname) -or ($ServerCertObject.DnsNameList -match $hostname)) -AND $ServerCertObject.Issuer -notmatch $ServerCertObject.Subject){ Write-Output "Success: Certificate bound in IIS is valid:" Write-Output "" Write-Output "Subject: $($ServerCertObject.Subject)" Write-Output "" Write-Output "Thumbprint: $($ServerCertObject.Thumbprint)" Write-Output "" Write-Output "Valid Until: $($ServerCertObject.NotAfter)" Write-Output "" Write-Output "If this NDES server is in your perimeter network, please ensure the external hostname is shown below:" $DNSNameList = $ServerCertObject.DNSNameList.unicode Write-Output "" Write-Output "Internal and External hostnames: $($DNSNameList)" Log-ScriptEvent $LogFilePath "Certificate bound in IIS is valid. Subject:$($ServerCertObject.Subject)|Thumbprint:$($ServerCertObject.Thumbprint)|ValidUntil:$($ServerCertObject.NotAfter)|Internal&ExternalHostnames:$($DNSNameList)" NDES_Validation 1 } else { Write-Output "Error: The certificate bound in IIS is not valid for use. Reason:" Write-Output "" if ($ServerCertObject.EnhancedKeyUsageList -match $serverAuthEKU) { $EKUValid = $true } else { $EKUValid = $false Write-Output "Correct EKU: $($EKUValid)" Write-Output "" } if ($ServerCertObject.Subject -match $hostname) { $SubjectValid = $true } else { $SubjectValid = $false Write-Output "Correct Subject: $($SubjectValid)" Write-Output "" } if ($SelfSigned -eq $false){ Out-Null } else { Write-Output "Is Self-Signed: $($SelfSigned)" Write-Output "" } Write-Output 'Please review "Step 4 - Configure NDES for use with Intune>To Install and bind certificates on the NDES Server".' Write-Output "URL: https://docs.microsoft.com/en-us/intune/certificates-scep-configure#configure-your-infrastructure" Log-ScriptEvent $LogFilePath "The certificate bound in IIS is not valid for use. CorrectEKU=$($EKUValid)|CorrectSubject=$($SubjectValid)|IsSelfSigned=$($SelfSigned)" NDES_Validation 3 } #endregion ################################################################# #region Checking Client certificate. Write-Output "" Write-Output "......................................................." Write-Output "" Write-Output "Checking Client certificate (NDES Policy module) is valid for use..." Write-Output "" Log-ScriptEvent $LogFilePath "Checking Client certificate (NDES Policy module) is valid for use" NDES_Validation 1 $hostname = ([System.Net.Dns]::GetHostByName(($env:computerName))).hostname $clientAuthEku = "1.3.6.1.5.5.7.3.2" # Client Authentication $NDESCertThumbprint = (Get-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Cryptography\MSCEP\Modules\NDESPolicy -Name NDESCertThumbprint).NDESCertThumbprint $ClientCertObject = Get-ChildItem Cert:\LocalMachine\My\$NDESCertThumbprint if ($ClientCertObject.Issuer -match $ClientCertObject.Subject){ $ClientCertSelfSigned = $true } else { $ClientCertSelfSigned = $false } if ($ClientCertObject.EnhancedKeyUsageList -match $clientAuthEku -AND $ClientCertObject.Subject -match $hostname -AND $ClientCertObject.Issuer -notmatch $ClientCertObject.Subject){ Write-Output "Success: Client certificate bound to NDES Connector is valid:" Write-Output "" Write-Output "Subject: $($ClientCertObject.Subject)" Write-Output "" Write-Output "Thumbprint: $($ClientCertObject.Thumbprint)" Write-Output "" Write-Output "Valid Until: $($ClientCertObject.NotAfter)" Log-ScriptEvent $LogFilePath "Client certificate bound to NDES Connector is valid. Subject:$($ClientCertObject.Subject)|Thumbprint:$($ClientCertObject.Thumbprint)|ValidUntil:$($ClientCertObject.NotAfter)" NDES_Validation 1 } else { Write-Output "Error: The certificate bound to the NDES Connector is not valid for use. Reason:" Write-Output if ($ClientCertObject.EnhancedKeyUsageList -match $clientAuthEku) { $ClientCertEKUValid = $true } else { $ClientCertEKUValid = $false Write-Output "Correct EKU: $($ClientCertEKUValid)" Write-Output "" } if ($ClientCertObject.Subject -match $hostname) { $ClientCertSubjectValid = $true } else { $ClientCertSubjectValid = $false Write-Output "Correct Subject: $($ClientCertSubjectValid)" Write-Output "" } if ($ClientCertSelfSigned -eq $false){ Out-Null } else { Write-Output "Is Self-Signed: $($ClientCertSelfSigned)" Write-Output "" } Write-Output 'Please review "Step 4 - Configure NDES for use with Intune>To Install and bind certificates on the NDES Server".' Write-Output "URL: https://docs.microsoft.com/en-us/intune/certificates-scep-configure#configure-your-infrastructure" Log-ScriptEvent $LogFilePath "The certificate bound to the NDES Connector is not valid for use. CorrectEKU=$($ClientCertEKUValid)|CorrectSubject=$($ClientCertSubjectValid)|IsSelfSigned=$($ClientCertSelfSigned)" NDES_Validation 3 } #endregion ################################################################# #region Checking behaviour of internal NDES URL Write-Output "" Write-Output "......................................................." $hostname = ([System.Net.Dns]::GetHostByName(($env:computerName))).hostname Write-Output "" Write-Output "Checking behaviour of internal NDES URL: " Write-Output "https://$hostname/certsrv/mscep/mscep.dll" Write-Output "" Log-ScriptEvent $LogFilePath "Checking behaviour of internal NDES URL" NDES_Validation 1 Log-ScriptEvent $LogFilePath "Https://$hostname/certsrv/mscep/mscep.dll" NDES_Validation 1 $Statuscode = try {(Invoke-WebRequest -Uri https://$hostname/certsrv/mscep/mscep.dll).statuscode} catch {$_.Exception.Response.StatusCode.Value__} if ($statuscode -eq "200"){ Write-Output "Error: https://$hostname/certsrv/mscep/mscep.dll returns 200 OK. This usually signifies an error with the Intune Connector registering itself or not being installed." Log-ScriptEvent $LogFilePath "https://$hostname/certsrv/mscep/mscep.dll returns 200 OK. This usually signifies an error with the Intune Connector registering itself or not being installed" NDES_Validation 3 } elseif ($statuscode -eq "403"){ Write-Output "Trying to retrieve CA Capabilitiess..." Write-Output "" $Newstatuscode = try {(Invoke-WebRequest -Uri "https://$hostname/certsrv/mscep/mscep.dll?operation=GetCACaps&message=test").statuscode} catch {$_.Exception.Response.StatusCode.Value__} if ($Newstatuscode -eq "200"){ $CACaps = (Invoke-WebRequest -Uri "https://$hostname/certsrv/mscep?operation=GetCACaps&message=test").content } if ($CACaps){ Write-Output "Success: CA Capabilities retrieved:" Write-Output "" Write-Output $CACaps Log-ScriptEvent $LogFilePath "CA Capabilities retrieved:$CACaps" NDES_Validation 1 } } else { Write-Output "Error: Unexpected Error code! This usually signifies an error with the Intune Connector registering itself or not being installed" Write-Output "Expected value is a 403. We received a $($Statuscode). This could be down to a missing reboot post policy module install. Verify last boot time and module install time further down the validation." Log-ScriptEvent $LogFilePath "Unexpected Error code. Expected:403|Received:$Statuscode" NDES_Validation 3 } #endregion ################################################################# #region Checking Servers last boot time Write-Output "" Write-Output "......................................................." Write-Output "" Write-Output "Checking Servers last boot time..." Write-Output "" Log-ScriptEvent $LogFilePath "Checking Servers last boot time" NDES_Validation 1 $LastBoot = (Get-WmiObject win32_operatingsystem | select csname, @{LABEL='LastBootUpTime' ;EXPRESSION={$_.ConverttoDateTime($_.lastbootuptime)}}).lastbootuptime Write-Output "Server last rebooted: $($LastBoot). Please ensure a reboot has taken place _after_ all registry changes and installing the NDES Connector. IISRESET is _not_ sufficient." Log-ScriptEvent $LogFilePath "LastBootTime:$LastBoot" NDES_Validation 1 #endregion ################################################################# #region Checking Intune Connector is installed Write-Output "" Write-Output "......................................................." Write-Output "" Write-Output "Checking Intune Connector is installed..." Write-Output "" Log-ScriptEvent $LogFilePath "Checking Intune Connector is installed" NDES_Validation 1 if ($IntuneConnector = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate | ? {$_.DisplayName -eq "Microsoft Intune Connector"}){ Write-Output "Success: $($IntuneConnector.DisplayName) was installed on " Write-Output "$($IntuneConnector.InstallDate) " Write-Output "and is version $($IntuneConnector.DisplayVersion)" Log-ScriptEvent $LogFilePath "ConnectorVersion:$IntuneConnector" NDES_Validation 1 } else { Write-Output "Error: Intune Connector not installed" Write-Output 'Please review "Step 5 - Enable, install, and configure the Intune certificate connector".' Write-Output "URL: https://docs.microsoft.com/en-us/intune/certificates-scep-configure#configure-your-infrastructure" Write-Output "" Log-ScriptEvent $LogFilePath "ConnectorNotInstalled" NDES_Validation 3 } #endregion ################################################################# #region Checking Intune Connector registry keys (KeyRecoveryAgentCertificate, PfxSigningCertificate and SigningCertificate) Write-Output "" Write-Output "......................................................." Write-Output "" Write-Output "Checking Intune Connector registry keys are intact" Write-Output "" Log-ScriptEvent $LogFilePath "Checking Intune Connector registry keys are intact" NDES_Validation 1 $ErrorActionPreference = "SilentlyContinue" $KeyRecoveryAgentCertificate = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MicrosoftIntune\NDESConnector\KeyRecoveryAgentCertificate" $PfxSigningCertificate = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MicrosoftIntune\NDESConnector\PfxSigningCertificate" $SigningCertificate = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MicrosoftIntune\NDESConnector\SigningCertificate" if (-not ($KeyRecoveryAgentCertificate)){ Write-Output "Error: KeyRecoveryAgentCertificate Registry key does not exist." Write-Output "" Log-ScriptEvent $LogFilePath "KeyRecoveryAgentCertificate Registry key does not exist." NDES_Validation 3 } else { $KeyRecoveryAgentCertificatePresent = (Get-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\MicrosoftIntune\NDESConnector\ -Name KeyRecoveryAgentCertificate).KeyRecoveryAgentCertificate if (-not ($KeyRecoveryAgentCertificatePresent)) { Write-Output "KeyRecoveryAgentCertificate registry key exists but has no value" Log-ScriptEvent $LogFilePath "KeyRecoveryAgentCertificate missing Value" NDES_Validation 2 } else { Write-Output "Success: KeyRecoveryAgentCertificate registry key exists" Log-ScriptEvent $LogFilePath "KeyRecoveryAgentCertificate registry key exists" NDES_Validation 1 } } if (-not ($PfxSigningCertificate)){ Write-Output "Error: PfxSigningCertificate Registry key does not exist." Write-Output "" Log-ScriptEvent $LogFilePath "PfxSigningCertificate Registry key does not exist." NDES_Validation 3 } else { $PfxSigningCertificatePresent = (Get-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\MicrosoftIntune\NDESConnector\ -Name PfxSigningCertificate).PfxSigningCertificate if (-not ($PfxSigningCertificatePresent)) { Write-Output "PfxSigningCertificate registry key exists but has no value" Log-ScriptEvent $LogFilePath "PfxSigningCertificate missing Value" NDES_Validation 2 } else { Write-Output "Success: PfxSigningCertificate registry keys exists" Log-ScriptEvent $LogFilePath "PfxSigningCertificate registry key exists" NDES_Validation 1 } } if (-not ($SigningCertificate)){ Write-Output "Error: SigningCertificate Registry key does not exist." Write-Output "" Log-ScriptEvent $LogFilePath "SigningCertificate Registry key does not exist" NDES_Validation 3 } else { $SigningCertificatePresent = (Get-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\MicrosoftIntune\NDESConnector\ -Name SigningCertificate).SigningCertificate if (-not ($SigningCertificatePresent)) { Write-Output "SigningCertificate registry key exists but has no value" Log-ScriptEvent $LogFilePath "SigningCertificate registry key exists but has no value" NDES_Validation 2 } else { Write-Output "Success: SigningCertificate registry key exists" Log-ScriptEvent $LogFilePath "SigningCertificate registry key exists" NDES_Validation 1 } } $ErrorActionPreference = "Continue" #endregion ################################################################# #region Checking eventlog for pertinent errors $ErrorActionPreference = "SilentlyContinue" $EventLogCollDays = ((Get-Date).AddDays(-5)) #Number of days to go back in the event log Write-Output "" Write-Output "......................................................." Write-Output "" Write-Output "Checking Event logs for pertinent errors..." Write-Output "" Log-ScriptEvent $LogFilePath "Checking Event logs for pertinent errors" NDES_Validation 1 if (-not (Get-EventLog -LogName "Microsoft Intune Connector" -EntryType Error -After $EventLogCollDays -ErrorAction silentlycontinue)) { Write-Output "Success: No errors found in the Microsoft Intune Connector" Write-Output "" Log-ScriptEvent $LogFilePath "No errors found in the Microsoft Intune Connector" NDES_Validation 1 } else { Write-Output "Errors found in the Microsoft Intune Connector Event log. Please see below for the most recent 5, and investigate further in Event Viewer." Write-Output "" $EventsCol1 = (Get-EventLog -LogName "Microsoft Intune Connector" -EntryType Error -After $EventLogCollDays -Newest 5 | select TimeGenerated,Source,Message) $EventsCol1 | fl Log-ScriptEvent $LogFilePath "Errors found in the Microsoft Intune Connector Event log" NDES_Eventvwr 3 $i = 0 $count = @($EventsCol1).count foreach ($item in $EventsCol1) { Log-ScriptEvent $LogFilePath "$($EventsCol1[$i].TimeGenerated);$($EventsCol1[$i].Message);$($EventsCol1[$i].Source)" NDES_Eventvwr 3 $i++ } } if (-not (Get-EventLog -LogName "Application" -EntryType Error -Source NDESConnector,Microsoft-Windows-NetworkDeviceEnrollmentService -After $EventLogCollDays -ErrorAction silentlycontinue)) { Write-Output "Success: No errors found in the Application log from source NetworkDeviceEnrollmentService or NDESConnector" Write-Output "" Log-ScriptEvent $LogFilePath "No errors found in the Application log from source NetworkDeviceEnrollmentService or NDESConnector" NDES_Validation 1 } else { Write-Output "Errors found in the Application Event log for source NetworkDeviceEnrollmentService or NDESConnector. Please see below for the most recent 5, and investigate further in Event Viewer." Write-Output "" $EventsCol2 = (Get-EventLog -LogName "Application" -EntryType Error -Source NDESConnector,Microsoft-Windows-NetworkDeviceEnrollmentService -After $EventLogCollDays -Newest 5 | select TimeGenerated,Source,Message) $EventsCol2 |fl $i = 0 $count = @($EventsCol2).count foreach ($item in $EventsCol2) { Log-ScriptEvent $LogFilePath "$($EventsCol2[$i].TimeGenerated);$($EventsCol2[$i].Message);$($EventsCol2[$i].Source)" NDES_Eventvwr 3 $i++ } } $ErrorActionPreference = "Continue" #endregion ################################################################# #region Zip up logfiles Write-Output "" Write-Output "......................................................." Write-Output "" Write-Output "Log Files..." Write-Output "" if ($unattend) { Write-Output "Automatically gathering files." $LogFileCollectionConfirmation = "y" } else { Write-Output "Do you want to gather troubleshooting files? This includes IIS, NDES Connector, NDES Plugin, CRP, and MSCEP log files, in addition to the SCEP template configuration. [Y]es, [N]o:" $LogFileCollectionConfirmation = Read-Host } if ($LogFileCollectionConfirmation -eq "y"){ $IISLogPath = (Get-WebConfigurationProperty "/system.applicationHost/sites/siteDefaults" -name logfile.directory).Value + "\W3SVC1" -replace "%SystemDrive%",$env:SystemDrive $IISLogs = Get-ChildItem $IISLogPath| Sort-Object -Descending -Property LastWriteTime | Select-Object -First 3 # redundant. already collected by ODC #$NDESConnectorLogs = Get-ChildItem "C:\Program Files\Microsoft Intune\NDESConnectorSvc\Logs\Logs\NDESConnector*" | Sort-Object -Descending -Property LastWriteTime | Select-Object -First 3 #$NDESPluginLogs = Get-ChildItem "C:\Program Files\Microsoft Intune\NDESPolicyModule\Logs\NDESPlugin.log" $MSCEPLogs = Get-ChildItem "c:\users\*\mscep.log" | Sort-Object -Descending -Property LastWriteTime | Select-Object -First 3 $CRPLogs = Get-ChildItem "C:\Program Files\Microsoft Intune\NDESConnectorSvc\Logs\Logs\CertificateRegistrationPoint*" | Sort-Object -Descending -Property LastWriteTime | Select-Object -First 3 foreach ($IISLog in $IISLogs){ Copy-Item -Path $IISLog.FullName -Destination $TempDirPath } foreach ($NDESConnectorLog in $NDESConnectorLogs){ Copy-Item -Path $NDESConnectorLog.FullName -Destination $TempDirPath } foreach ($NDESPluginLog in $NDESPluginLogs){ Copy-Item -Path $NDESPluginLog.FullName -Destination $TempDirPath } foreach ($MSCEPLog in $MSCEPLogs){ Copy-Item -Path $MSCEPLog.FullName -Destination $TempDirPath } foreach ($CRPLog in $CRPLogs){ Copy-Item -Path $CRPLogs.FullName -Destination $TempDirPath } $SCEPUserCertTemplateOutputFilePath = "$($TempDirPath)\SCEPUserCertTemplate.txt" certutil -v -template $SCEPUserCertTemplate > $SCEPUserCertTemplateOutputFilePath Log-ScriptEvent $LogFilePath "Collecting server logs" NDES_Validation 1 Add-Type -assembly "system.io.compression.filesystem" $Currentlocation = $env:temp $date = Get-Date -Format ddMMyyhhmm [io.compression.zipfile]::CreateFromDirectory($TempDirPath, "$($Currentlocation)\$($date)-Logs-$($hostname).zip") Write-Output "" Write-Output "Success: Log files copied to $($Currentlocation)\$($date)-Logs-$($hostname).zip" Write-Output "" # for ODC if ($unattend ){ if ( -not (test-path $outputPath) ) { mkdir $outputPath -Force } Move-Item $TempDirPath\* $outputPath -Force -ErrorAction SilentlyContinue } # Cleanup rmdir -Recurse -Force -ErrorAction SilentlyContinue -Path $TempDirPath } else { Log-ScriptEvent $LogFilePath "Do not collect logs" NDES_Validation 1 $WriteLogOutputPath = $True } #endregion ################################################################# } else { Write-Output "" Write-Output "......................................................." Write-Output "" Write-Output "Incorrect variables. Please run the script again..." Write-Output "" Write-Output "Exiting................................................" Write-Output "" exit } } else { "Not on NDES Server. Exiting" } Get-Service | fl * if (Test-Path -Path 'HKLM:\Software\Microsoft\PolicyManager\current\device') { echo "`r`n===========================================`r`n`t`t Get-ChildItem 'HKLM:\Software\Microsoft\PolicyManager\current\device\*' -Recurse `r`n===========================================`r`n" Get-ChildItem 'HKLM:\Software\Microsoft\PolicyManager\current\device\*' -Recurse } else { "Warning - no policies found under HKLM:\Software\Microsoft\PolicyManager\current\device" } if (Test-Path -Path 'HKLM:\Software\Policies\Microsoft') { echo "`r`n===========================================`r`n`t`t Get-ChildItem 'HKLM:\Software\Policies\Microsoft' -Recurse `r`n===========================================`r`n" Get-ChildItem 'HKLM:\Software\Policies\Microsoft' -Recurse } else { "Warning - no policies found under HKLM:\Software\Policies\Microsoft" } if ( (dir Cert:\LocalMachine\My).Count -gt 0) { dir Cert:\LocalMachine\My | Select-Object * -ExpandProperty Extensions -ExcludeProperty RawData, PrivateKey } else { "Warning - no certs found in Local Machine personal certificate store (cert:\localmachine\my)" } if ( (dir Cert:\CurrentUser\My).Count -gt 0) { dir Cert:\CurrentUser\My | Select-Object * -ExpandProperty Extensions -ExcludeProperty RawData, PrivateKey } else { "Warning - no certs found in Local Machine personal certificate store (cert:\localmachine\my)" } dir $env:systemroot\IMECache -ErrorAction SilentlyContinue dir "${env:ProgramFiles(x86)}\Microsoft Intune Management Extension" -Recurse -ErrorAction SilentlyContinue "Service information" $ErrorActionPreference = "Stop" $Error.Clear() try { Get-Service IntuneManagementExtension |fl * } catch { "IntuneManagementExtension service not installed. Verify that device is compliant and marked as corporate ownership." $Error } "Scheduled task information" try { Get-ScheduledTask  -TaskName "Intune Management Extension Health Evaluation"  -ErrorAction SilentlyContinue| Select-Object * -ExpandProperty CimInstanceProperties Get-ScheduledTask  -TaskName "Intune Management Extension Health Evaluation" -ErrorAction SilentlyContinue | Get-ScheduledTaskInfo  | Select-Object * -ExpandProperty CimInstanceProperties } catch { "Warning: Unable to find IME scheduled tasks" $Error } # workaround $ErrorActionPreference = "silentlycontinue" foreach ($file in $Package.files.file) { $file | fl * $expandedPath = [System.Environment]::ExpandEnvironmentVariables($file.value) $expandedPath if (test-path $expandedPath) { [string]$team = $file.team $newFolder = [System.Environment]::ExpandEnvironmentVariables( $(join-path "$ResultRootDirectory\Intune\Files" $team) ) mkdir $newFolder -Force -errorAction SilentlyContinue $FilesToCheck = dir $expandedPath foreach ($fileToCheck in $FilesToCheck) { if (test-path $fileToCheck){ [string]$team = $file.team $parentFolder = [System.Environment]::ExpandEnvironmentVariables( $(join-path "$ResultRootDirectory\Intune\Files" $team) ) $renamedFile = $env:COMPUTERNAME + "_" + ( Split-Path $fileToCheck -leaf) $myfullPath = Join-Path $parentFolder $renamedFile if (Test-Path $myfullPath){ #file found, skip "found $myfullPath" } else { if (-not (Test-Path $parentFolder) ) { $nil = mkdir $parentFolder } copy $fileToCheck $myfullPath } } } } } function RunCommand { Param ([string]$cmdToRun) echo "`r`n===========================================`r`n`t`t $cmdToRun `r`n===========================================`r`n" try { Invoke-Expression($cmdToRun) -ErrorAction Stop } catch { $error[0].ToString()} } RunCommand -cmdToRun "Get-WinEvent -ErrorAction SilentlyContinue -ListLog * | Select-Object LogName, LogFilePath, FileSize, LastWriteTime, IsEnabled | Sort IsEnabled, LogName" RunCommand -cmdToRun "dir $env:windir\system32\winevt\logs | select FullName, Length, LastWriteTime" function RunCommand { Param ([string]$cmdToRun) $line = "=" * 120 echo "`r`n$line`r`n`t`t $cmdToRun `r`n$line`r`n" try { Invoke-Expression($cmdToRun) -ErrorAction Stop } catch { $error[0].ToString()} } RunCommand -cmdToRun "Get-CimInstance -ClassName AntiVirusProduct -Namespace ROOT\SecurityCenter2" RunCommand -cmdToRun "Get-CimInstance -ClassName AntiSpywareProduct -Namespace ROOT\SecurityCenter2" RunCommand -cmdToRun "Get-CimInstance -ClassName FirewallProduct -Namespace ROOT\SecurityCenter2" RunCommand -cmdToRun "Get-CimInstance -ClassName MSFT_MpComputerStatus -Namespace ROOT\Microsoft\ProtectionManagement" RunCommand -cmdToRun "Get-CimInstance -ClassName AntimalwareDetectionStatus -Namespace ROOT\Microsoft\SecurityClient" RunCommand -cmdToRun "Get-CimInstance -ClassName AntimalwareHealthStatus -Namespace ROOT\Microsoft\SecurityClient" RunCommand -cmdToRun "Get-CimInstance -ClassName AntimalwareInfectionStatus -Namespace ROOT\Microsoft\SecurityClient" RunCommand -cmdToRun "Get-CimInstance -ClassName Malware -Namespace ROOT\Microsoft\SecurityClient" RunCommand -cmdToRun "Get-CimInstance -ClassName ProtectionTechnologyStatus -Namespace ROOT\Microsoft\SecurityClient" RunCommand -cmdToRun "Get-CimInstance -ClassName SerializableToXml -Namespace ROOT\Microsoft\SecurityClient" RunCommand -cmdToRun "Get-CimInstance -ClassName Win32_ProviderEx -Namespace ROOT\Microsoft\SecurityClient" RunCommand -cmdToRun "Get-CimInstance -ClassName AntimalwareDetectionStatus -Namespace ROOT\Microsoft\SecurityClient" Get-BitsTransfer -AllUsers -Verbose |fl * if (test-path c:\mdmtrace) { $outputPath = "$env:temp\CollectedData\Intune\Commands\Debug" $x = if (-not (Test-Path $outputPath)) { mkdir $outputPath -Force} copy c:\mdmtrace\* $outputpath -force } $apscript = @' # From https://oofhours.com/2020/02/17/what-happened-during-windows-autopilot-esp-decode-it/ [CmdletBinding()] param( [Parameter(Mandatory=$False)] [String] $CABFile = $null, [Parameter(Mandatory=$False)] [Switch] $Online = $false, [Parameter(Mandatory=$False)] [Switch] $AllSessions = $false ) Begin { # If using a CAB file, load up the registry information if ($CABFile) { # Extract the .reg file if (-not (Test-Path "$($env:TEMP)\ESPStatus.tmp")) { New-Item -Path "$($env:TEMP)\ESPStatus.tmp" -ItemType "directory" | Out-Null } $null = & expand.exe "$CABFile" -F:MdmDiagReport_RegistryDump.reg "$($env:TEMP)\ESPStatus.tmp\" if (-not (Test-Path "$($env:TEMP)\ESPStatus.tmp\MdmDiagReport_RegistryDump.reg")) { Write-Error "Unable to extract registrion information from $CABFile" } # Edit the path in the .reg file $content = Get-Content -Path "$($env:TEMP)\ESPStatus.tmp\MdmDiagReport_RegistryDump.reg" $content = $content -replace "\[HKEY_CURRENT_USER\\", "[HKEY_CURRENT_USER\ESPStatus.tmp\USER\" $content = $content -replace "\[HKEY_LOCAL_MACHINE\\", "[HKEY_CURRENT_USER\ESPStatus.tmp\MACHINE\" $content = $content -replace '^ "','"' $content = $content -replace '^ @','@' $content = $content -replace 'DWORD:','dword:' "Windows Registry Editor Version 5.00`n" | Set-Content -Path "$($env:TEMP)\ESPStatus.tmp\MdmDiagReport_Edited.reg" $content | Add-Content -Path "$($env:TEMP)\ESPStatus.tmp\MdmDiagReport_Edited.reg" # Remove the registry info if it exists if (Test-Path "HKCU:\ESPStatus.tmp") { Remove-Item -Path "HKCU:\ESPStatus.tmp" -Recurse -Force } # Import the .reg file $null = & reg.exe IMPORT "$($env:TEMP)\ESPStatus.tmp\MdmDiagReport_Edited.reg" 2>&1 # Configure the (not live) constants $script:autopilotDiagPath = "HKCU:\ESPStatus.tmp\MACHINE\software\microsoft\provisioning\Diagnostics\Autopilot" $script:omadmPath = "HKCU:\ESPStatus.tmp\MACHINE\software\microsoft\provisioning\OMADM" $script:path = "HKCU:\ESPStatus.tmp\MACHINE\Software\Microsoft\Windows\Autopilot\EnrollmentStatusTracking\ESPTrackingInfo\Diagnostics" $script:msiPath = "HKCU:\ESPStatus.tmp\MACHINE\Software\Microsoft\EnterpriseDesktopAppManagement" $script:officePath = "HKCU:\ESPStatus.tmp\MACHINE\Software\Microsoft\OfficeCSP" $script:sidecarPath = "HKCU:\ESPStatus.tmp\MACHINE\Software\Microsoft\IntuneManagementExtension\Win32Apps" } else { # Configure live constants $script:autopilotDiagPath = "HKLM:\software\microsoft\provisioning\Diagnostics\Autopilot" $script:omadmPath = "HKLM:\software\microsoft\provisioning\OMADM" $script:path = "HKLM:\Software\Microsoft\Windows\Autopilot\EnrollmentStatusTracking\ESPTrackingInfo\Diagnostics" $script:msiPath = "HKLM:\Software\Microsoft\EnterpriseDesktopAppManagement" $script:officePath = "HKLM:\Software\Microsoft\OfficeCSP" $script:sidecarPath = "HKLM:\Software\Microsoft\IntuneManagementExtension\Win32Apps" } # Configure other constants $script:statusCodes = @{"10" = "Initialized"; "20" = "Download In Progress"; "25" = "Pending Download Retry"; "30" = "Download Failed"; "40" = "Download Completed"; "48" = "Pending User Session"; "50" = "Enforcement In Progress"; "55" = "Pending Enforcement Retry"; "60" = "Enforcement Failed"; 70 = "Success / Enforcement Completed"} $script:espStatus = @{"1" = "Not Installed"; "2" = "Downloading / Installing"; "3" = "Success / Installed"; "4" = "Error / Failed"} $script:policyStatus = @{"0" = "Not Processed"; "1" = "Processed"} $script:sidecarMSI = @("093ea47b-ef2c-4f46-a022-6f57a50e39a2","be41a3fa-539c-47dc-88ca-74e65b7a7ec5") } Process { #------------------------ # Functions #------------------------ Function ProcessApps() { param ( [Parameter(Mandatory=$true,ValueFromPipeline=$True)] [Microsoft.Win32.RegistryKey] $currentKey, [Parameter(Mandatory=$true)] $currentUser ) Begin { Write-Output "Apps:" } Process { Write-Output " $($currentKey.PSChildName)" $currentKey.Property | % { if ($_.StartsWith("./Device/Vendor/MSFT/EnterpriseDesktopAppManagement/MSI/")) { $msiKey = [URI]::UnescapeDataString(($_.Split("/"))[6]) $fullPath = "$msiPath\$currentUser\MSI\$msiKey" if (Test-Path $fullPath) { $status = Get-ItemPropertyValue -Path $fullPath -Name Status } else { $status = "Not found" } if ($sidecarMSI -contains $msiKey) { $msiKey = "Intune Management Extensions ($($msiKey))" } elseif ($Online) { $found = $apps | ? {$_.ProductCode -contains $msiKey} $msiKey = "$($found.DisplayName) ($($msiKey))" } if ($status -eq 70) { Write-Output " MSI $msiKey : $status ($($statusCodes[$status]))" } else { Write-Output " MSI $msiKey : $status ($($statusCodes[$status]))" } } elseif ($_.StartsWith("./Vendor/MSFT/Office/Installation/")) { $officeKey = [URI]::UnescapeDataString(($_.Split("/"))[5]) $fullPath = "$officepath\$officeKey" if (Test-Path $fullPath) { $status = Get-ItemPropertyValue -Path $fullPath -Name FinalStatus -ErrorAction Ignore if ($status -eq $null) { $status = Get-ItemPropertyValue -Path $fullPath -Name Status -ErrorAction Ignore if ($status -eq $null) { $status = "None" } } } else { # Office CSP info isn't available, so just get the MSI status, where 1 = done $status = Get-ItemPropertyValue -Path $currentKey.PSPath -Name $_ if ($status -eq 1) { $status = 70 } } if ($status -eq 70) { Write-Output " Office $officeKey : $status ($($statusCodes[$status]))" } else { Write-Output " Office $officeKey : $status ($($statusCodes[$status]))" } } else { Write-Output " $_ : Unknown app" } } } } Function ProcessModernApps() { param ( [Parameter(Mandatory=$true,ValueFromPipeline=$True)] [Microsoft.Win32.RegistryKey] $currentKey, [Parameter(Mandatory=$true)] $currentUser ) Begin { Write-Output "Modern Apps:" } Process { Write-Output " $($currentKey.PSChildName)" $currentKey.Property | % { $status = (Get-ItemPropertyValue -path $currentKey.PSPath -Name $_).ToString() if ($_.StartsWith("./User/Vendor/MSFT/EnterpriseModernAppManagement/AppManagement/")) { $appID = [URI]::UnescapeDataString(($_.Split("/"))[7]) $type = "User UWP" } elseif ($_.StartsWith("./Device/Vendor/MSFT/EnterpriseModernAppManagement/AppManagement/")) { $appID = [URI]::UnescapeDataString(($_.Split("/"))[7]) $type = "Device UWP" } else { $appID = $_ $type = "Unknown UWP" } if ($status -eq "1") { Write-Output " $type $appID : $status ($($policyStatus[$status]))" } else { Write-Output " $type $appID : $status ($($policyStatus[$status]))" } } } } Function ProcessSidecar() { param ( [Parameter(Mandatory=$true,ValueFromPipeline=$True)] [Microsoft.Win32.RegistryKey] $currentKey, [Parameter(Mandatory=$true)] $currentUser ) Begin { Write-Output "Sidecar apps:" } Process { Write-Output " $($currentKey.PSChildName)" $currentKey.Property | % { $win32Key = [URI]::UnescapeDataString(($_.Split("/"))[9]) $status = Get-ItemPropertyValue -path $currentKey.PSPath -Name $_ if ($Online) { $found = $apps | ? {$win32Key -match $_.Id } $win32Key = "$($found.DisplayName) ($($win32Key))" } $appGuid = $win32Key.Substring(9) $sidecarApp = "$sidecarPath\$currentUser\$appGuid" $exitCode = "" if (Test-Path $sidecarApp) { $exitCode = Get-ItemPropertyValue -Path $sidecarApp -Name ExitCode -ErrorAction Ignore } if ($status -eq "3") { if ($exitCode -ne "") { Write-Output " Win32 $win32Key : $status ($($espStatus[$status.ToString()]), rc = $exitCode)" } else { Write-Output " Win32 $win32Key : $status ($($espStatus[$status.ToString()]))" } } else { if ($exitCode -ne "") { Write-Output " Win32 $win32Key : $status ($($espStatus[$status.ToString()]), rc = $exitCode)" } else { Write-Output " Win32 $win32Key : $status ($($espStatus[$status.ToString()]))" } } } } } Function ProcessPolicies() { param ( [Parameter(Mandatory=$true,ValueFromPipeline=$True)] [Microsoft.Win32.RegistryKey] $currentKey ) Begin { Write-Output "Policies:" } Process { Write-Output " $($currentKey.PSChildName)" $currentKey.Property | % { $status = Get-ItemPropertyValue -path $currentKey.PSPath -Name $_ Write-Output " Policy $_ : $status ($($policyStatus[$status.ToString()]))" } } } Function ProcessCerts() { param ( [Parameter(Mandatory=$true,ValueFromPipeline=$True)] [Microsoft.Win32.RegistryKey] $currentKey ) Begin { Write-Output "Certificates:" } Process { Write-Output " $($currentKey.PSChildName)" $currentKey.Property | % { $certKey = [URI]::UnescapeDataString(($_.Split("/"))[6]) $status = Get-ItemPropertyValue -path $currentKey.PSPath -Name $_ if ($Online) { $found = $policies | ? { $certKey.Replace("_","-") -match $_.Id } $certKey = "$($found.DisplayName) ($($certKey))" } if ($status -eq "1") { Write-Output " Cert $certKey : $status ($($policyStatus[$status.ToString()]))" } else { Write-Output " Cert $certKey : $status ($($policyStatus[$status.ToString()]))" } } } } Function GetIntuneObjects() { param ( [Parameter(Mandatory=$true)] [String] $uri ) Process { Write-Verbose "GET $uri" try { $response = Invoke-MSGraphRequest -Url $uri -HttpMethod Get $objects = $response.value $objectsNextLink = $response."@odata.nextLink" while ($objectsNextLink -ne $null){ $response = (Invoke-MSGraphRequest -Url $devicesNextLink -HttpMethod Get) $objectsNextLink = $response."@odata.nextLink" $objects += $response.value } return $objects } catch { Write-Error $_.Exception return $null break } } } #------------------------ # Main code #------------------------ # Make sure the tracking path exists if (-not (Test-Path $path)) { Write-Output "ESP diagnostics info does not (yet) exist." exit 0 } # If online, make sure we are able to authenticate if ($Online) { # Make sure we can connect $module = Import-Module Microsoft.Graph.Intune -PassThru -ErrorAction Ignore if (-not $module) { Write-Output "Installing module Microsoft.Graph.Intune" Install-Module Microsoft.Graph.Intune -Force } Import-Module Microsoft.Graph.Intune $graph = Connect-MSGraph Write-Output "Connected to tenant $($graph.TenantId)" # Get a list of apps Write-Output "Getting list of apps" $script:apps = GetIntuneObjects("https://graph.microsoft.com/beta/deviceAppManagement/mobileApps") # Get a list of policies (for certs) Write-Output "Getting list of policies" $script:policies = GetIntuneObjects("https://graph.microsoft.com/beta/deviceManagement/deviceConfigurations") } # Display Autopilot diag details if (Test-Path $autopilotDiagPath) { Write-Output "" Write-Output "AUTOPILOT DIAGNOSTICS" Write-Output "" $values = Get-ItemProperty "$autopilotDiagPath" Write-Output "TenantDomain: $($values.CloudAssignedTenantDomain)" Write-Output "TenantID: $($values.CloudAssignedTenantId)" Write-Output "OobeConfig: $($values.CloudAssignedOobeConfig)" $values = Get-ItemProperty "$autopilotDiagPath\EstablishedCorrelations" Write-Output "EntDMID: $($values.EntDMID)" if (Test-Path "$omadmPath\SyncML\ODJApplied") { Write-Output "ODJ applied: YES" } } # Process device ESP sessions Write-Output " " Write-Output "DEVICE ESP:" Write-Output " " if (Test-Path "$path\ExpectedMSIAppPackages") { $items = Get-ChildItem "$path\ExpectedMSIAppPackages" if ($AllSessions) { $items | ProcessApps -currentUser "S-0-0-00-0000000000-0000000000-000000000-000" } elseif ($items.Count -gt 0) { $items[$items.Count - 1] | ProcessApps -currentUser "S-0-0-00-0000000000-0000000000-000000000-000" } } if (Test-Path "$path\ExpectedModernAppPackages") { $items = Get-ChildItem "$path\ExpectedModernAppPackages" if ($AllSessions) { $items | ProcessModernApps -currentUser "S-0-0-00-0000000000-0000000000-000000000-000" } elseif ($items.Count -gt 0) { $items[$items.Count - 1] | ProcessModernApps -currentUser "S-0-0-00-0000000000-0000000000-000000000-000" } } if (Test-Path "$path\Sidecar") { $items = Get-ChildItem "$path\Sidecar" if ($AllSessions) { $items | ProcessSidecar -currentUser "00000000-0000-0000-0000-000000000000" } elseif ($items.Count -gt 0) { $items[$items.Count - 1] | ProcessSidecar -currentUser "00000000-0000-0000-0000-000000000000" } } if (Test-Path "$path\ExpectedPolicies") { $items = Get-ChildItem "$path\ExpectedPolicies" if ($AllSessions) { $items | ProcessPolicies } elseif ($items.Count -gt 0) { $items[$items.Count - 1] | ProcessPolicies } } if (Test-Path "$path\ExpectedSCEPCerts") { $items = Get-ChildItem "$path\ExpectedSCEPCerts" if ($AllSessions) { $items | ProcessCerts } elseif ($items.Count -gt 0) { $items[$items.Count - 1] | ProcessCerts } } # Process user ESP sessions Get-ChildItem "$path" | ? { $_.PSChildName.StartsWith("S-") } | % { $userPath = $_.PSPath $userSid = $_.PSChildName Write-Output " " Write-Output "USER ESP for $($userSid):" Write-Output " " if (Test-Path "$userPath\ExpectedMSIAppPackages") { $items = Get-ChildItem "$userPath\ExpectedMSIAppPackages" if ($AllSessions) { $items | ProcessApps -currentUser $userSid } elseif ($items.Count -gt 0) { $items[$items.Count - 1] | ProcessApps -currentUser $userSid } } if (Test-Path "$userPath\ExpectedModernAppPackages") { $items = Get-ChildItem "$userPath\ExpectedModernAppPackages" if ($AllSessions) { $items | ProcessModernApps -currentUser $userSid } elseif ($items.Count -gt 0) { $items[$items.Count - 1] | ProcessModernApps -currentUser $userSid } } if (Test-Path "$userPath\Sidecar") { $items = Get-ChildItem "$userPath\Sidecar" if ($AllSessions) { $items | ProcessSidecar -currentUser $userSid } elseif ($items.Count -gt 0) { $items[$items.Count - 1] | ProcessSidecar -currentUser $userSid } } if (Test-Path "$userPath\ExpectedPolicies") { $items = Get-ChildItem "$userPath\ExpectedPolicies" if ($AllSessions) { $items | ProcessPolicies } elseif ($items.Count -gt 0) { $items[$items.Count - 1] | ProcessPolicies } } if (Test-Path "$userPath\ExpectedSCEPCerts") { $items = Get-ChildItem "$userPath\ExpectedSCEPCerts" if ($AllSessions) { $items | ProcessCerts } elseif ($items.Count -gt 0) { $items[$items.Count - 1] | ProcessCerts } } } Write-Output "" } End { # Remove the registry info if it exists if (Test-Path "HKCU:\ESPStatus.tmp") { Remove-Item -Path "HKCU:\ESPStatus.tmp" -Recurse -Force } } '@ $outputPath = "$env:temp\CollectedData\Intune\Commands\Autopilot" $x = if (-not (Test-Path $outputPath)) { mkdir $outputPath -Force} $logfile = Join-Path $outputPath Get-AutopilotESPStatus.txt $important = Join-Path $outputPath "!_Important.txt" # workaround for process() script block limitation $apscript | out-file apinfo.ps1 . .\apinfo.ps1 | Out-File $logfile -Force del .\apinfo.ps1 echo "Please see internal KB 4570137 for more information regarding decoding Autopilot ETL logs." | Out-File $important -Force # https://gallery.technet.microsoft.com/scriptcenter/Show-Windows-Update-c7ee69bd $objSession = new-object -com "Microsoft.Update.Session" $objSearcher = $objSession.CreateupdateSearcher() $intCount = $objSearcher.GetTotalHistoryCount() $colHistory = $objSearcher.QueryHistory(0, $intCount) foreach ($objHistory in $colHistory) { $title = ($objHistory.Date).ToString("yyyy/MM/dd hh:mm UTC") + " " + $objHistory.Title + "`t" if ($objHistory.HResult -eq 0) { Write-Output "$title - Successfully installed" } elseif ($objHistory.HResult -eq -2145116140) { Write-Output "$title - Pending Reboot" } else { # Report errors for the past month if (($objHistory.Date).AddMonths(1) -gt (Get-Date)) { $hexErr = "0x$($objHistory.HResult.ToString("X8"))" Write-Output "$title - Failed to install. `tError: $hexErr" } } } Write-Output "=======================================================================================`r`n`r`n" Write-Output "============= Verbose Output ===============`r`n`r`n" Write-Output "=======================================================================================`r`n`r`n" # Verbose output foreach ($objHistory in $colHistory) { $o = New-Object PSObject $o | Add-Member -MemberType NoteProperty -Name Update $(Select-Object * -InputObject $objHistory -ExcludeProperty UninstallationSteps,Categories,UpdateIdentity | Out-String ) $o | Add-Member -MemberType NoteProperty -Name UpdateID -Value $($objHistory.UpdateIdentity | Out-String ) $o | Add-Member -MemberType NoteProperty -Name Categories -Value $($objHistory.Categories | Out-String ) "================================================================" "$($objHistory.Title | Out-String)" "================================================================" $o | fl * } # Windows update debug # Attempt to run using local tools first $ErrorActionPreference = "Stop" $Error.Clear() $line = "`*" * 120 function WaitOnSchTask { param([string]$taskName, [string]$OutFile = "c:\temp\winupdate_debug.txt" ) try { $status = (Get-ScheduledTask -TaskName $taskName).State [int]$timer = 0 while ( ($status -ne "Ready") -and ($timer -le 60) ) { $status = (Get-ScheduledTask -TaskName $taskName).State $timer += 5 sleep 5 } } catch [Microsoft.PowerShell.Cmdletization.Cim.CimJobException] { "Something went wrong. Scheduled task not found" | Out-file $OutFile -Force -Append -Encoding ascii } catch { "Something went wrong." | Out-file $OutFile -Force -Append -Encoding ascii $Error[0] | Out-file $OutFile -Force -Append -Encoding ascii $Error[0].Exception.GetType().fullname | Out-file $OutFile -Force -Append -Encoding ascii } } # write temp file $tempFilePath = Join-Path $env:temp "winupdatetemp.ps1" $tempfileContents = @' param( [string]$OutFile = "c:\temp\winupdate_debug.txt") [string]$computer = $env:COMPUTERNAME [string]$namespace = "ROOT\CIMV2\mdm\dmmap" [string[]]$classnames = @("MDM_DeviceUpdateCenter_Enrollment01", "MDM_Policy_Config01_Update02", "MDM_Policy_Result01_Update02", "MDM_Update", "MDM_Update_ApprovedUpdates01_01", "MDM_Update_FailedUpdates01_01" ,"MDM_Update_InstallableUpdates01_01", "MDM_Update_PendingRebootUpdates01_01", "MDM_Update_Rollback01") $Error.Clear() $ErrorActionPreference = "Stop" foreach ($classname in $classnames) { try { "=====================================" | Out-file $OutFile -Force -Append -Encoding ascii "CLASS : $classname " | Out-file $OutFile -Force -Append -Encoding ascii "=====================================" | Out-file $OutFile -Force -Append -Encoding ascii Get-WmiObject -Class $classname -Namespace $namespace ` |Select-Object * -ExcludeProperty PSComputerName, Scope, Path, Options, ClassPath, Properties, SystemProperties, Qualifiers, Site, Container ` | Format-List -Property [a-z]* | Out-file $OutFile -Force -Append -Encoding ascii } catch [System.Management.ManagementException] { # ignore - class not found because it is not populated } catch { $Error[0] $Error[0].Exception.GetType().fullname | fl * | Out-file $OutFile -Force -Append -Encoding ascii } } '@ $tempfileContents | Out-File $tempFilePath -Force # Launch process as system via scheduled task $TimeToRun = (Get-Date).AddSeconds(3) $taskName = "ODC Windows Update Debug" $folderPath = "$env:temp\CollectedData\Intune\Commands\Windows Update" $filepath = Join-Path $folderPath "$($env:COMPUTERNAME)_Windows_Updates_Debug.txt" # Create folder if it does not exist for uploader if ( -not ( Test-Path $folderPath -ErrorAction SilentlyContinue) ) { $nil = mkdir $folderPath -Force } $line | Out-File $filepath -Force -Encoding ascii "Starting update query using Scheduled Task as SYSTEM`r`n" | Out-File $filepath -Append -Force -Encoding ascii $line | Out-File $filepath -Force -Append -Encoding ascii $Trigger= New-ScheduledTaskTrigger -At $TimeToRun -Once $User= "NT AUTHORITY\SYSTEM" $Action= New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-File `"$tempFilePath`" -Nologo -OutFile `"$filepath`"" $nil = Register-ScheduledTask -TaskName $taskName -Trigger $Trigger -User $User -Action $Action -RunLevel Highest –Force $nil = Start-ScheduledTask -TaskName $taskName WaitOnSchTask -taskName $taskName -OutFile $filepath #cleanup $nil = Unregister-ScheduledTask -TaskName $taskName -TaskPath "\" -PassThru -Confirm:$false $x = if (-not (Test-Path $outputPath)) { mkdir $outputPath -Force} copy $env:ProgramData\microsoft\diagnosticlogcsp\collectors\*.etl . foreach ($file in $(dir *.etl)) { netsh trace convert $file } move *.txt $outputPath -Force del .\*DiagnosticLogCSP_Collector*.etl # AV settings function RunCommand { Param ([string]$cmdToRun) echo "`r`n===========================================`r`n`t`t $cmdToRun `r`n===========================================`r`n" try { Invoke-Expression($cmdToRun) -ErrorAction Stop } catch { $error[0].ToString()} } RunCommand Get-MpComputerStatus -Verbose RunCommand Get-MpPreference -Verbose RunCommand Get-MpThreatDetection reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Appraiser\GWX" Get-DeliveryOptimizationLog %windir%\system32\winevt\logs\System.evtx %windir%\system32\winevt\logs\Application.evtx %windir%\system32\winevt\logs\Security.evtx %windir%\system32\winevt\logs\*devicemanagement* %windir%\system32\winevt\logs\*powershell* %windir%\system32\winevt\logs\*workplace* %windir%\system32\winevt\logs\*user*device* %windir%\system32\winevt\logs\*operations* %windir%\system32\winevt\logs\*momlog* %windir%\system32\winevt\logs\*AAD*.evtx %windir%\system32\winevt\logs\Microsoft-Windows-Provisioning-* %windir%\system32\Winevt\Logs\Microsoft-Windows-DeviceSetupManager* %windir%\system32\winevt\logs\*appx* %windir%\system32\Winevt\Logs\Microsoft-Windows-Shell-Core%4Operational.evtx %windir%\system32\winevt\logs\*intune* %windir%\system32\winevt\logs\*bitlocker* %windir%\system32\Winevt\Logs\Microsoft-Windows-SENSE%4Operational.evtx %windir%\system32\Winevt\Logs\Microsoft-Windows-HelloForBusiness%4Operational.evtx %windir%\system32\winevt\logs\odj* %windir%\system32\winevt\logs\*-bits-* %windir%\system32\winevt\logs\Microsoft-Windows-ModernDeployment-* %windir%\system32\winevt\logs\*firewall* %windir%\system32\winevt\logs\*defender* %windir%\system32\winevt\logs\PFX* %windir%\system32\winevt\logs\*WMI* %windir%\system32\winevt\logs\Microsoft-Windows-WindowsUpdateClient* %windir%\system32\winevt\logs\Microsoft-Windows-NetworkProfile* %windir%\system32\winevt\logs\*ncrypt* %windir%\system32\winevt\logs\*PushNotifications* %ProgramFiles%\System Center Advisor\AgentData\Logs\* %ProgramFiles%\System Center Advisor\GatewayData\Logs\*.* %ALLUSERSPROFILE%\Microsoft\Microsoft Antimalware\Support\*.cab %ProgramData%\Microsoft\Microsoft Antimalware\Support\*.cab %ProgramFiles%\Microsoft Antimalware\Support\*.* %systemroot%\ServiceState\Autopilot\*.json %windir%\Provisioning\AutoPilot\AutoPilotConfigurationFile.json %SystemRoot%\Logs\MeasuredBoot\*.log %systemroot%\Logs\CBS\*.log %SMS_LOG_PATH%\*.* %systemroot%\ccmsetup\Logs\* %ProgramFiles%\Microsoft Online Directory Sync\*.log %ProgramData%\Microsoft\Windows Intune Exchange Connector\*.* %ProgramData%\Microsoft\Windows Intune Exchange Connector\Logs\*.* odc_debug.log %LOCALAPPDATA%\Temp\*.log %ProgramData%\Microsoft\IntuneManagementExtension\Logs\* %ProgramData%\microsoft\diagnosticlogcsp\collectors\* %ProgramFiles%\Microsoft Intune\ODJConnector\ODJConnectorUI\*.log %ProgramFiles%\Microsoft\OnlineManagement\PolicyAgent\ReportCache\3DA21691-E39D-4DA6-8A4B-B43877BCB1B7\*.xml %systemroot%\temp\stdout.log %temp%\supportconsole*.* %windir%\PolicyClient*.log %windir%\SoftwareDistribution\ReportingEvents*.log %windir%\Logs\HomeGroup\*.* %LOCALAPPDATA%\Microsoft\OnlineManagement\Logs\clientui.log %LOCALAPPDATA%\Microsoft\Windows\clientui.log %ProgramFiles%\Microsoft\OnlineManagement\Logs\*.log %ProgramFiles%\Microsoft\OnlineManagement\PolicyAgent\InventoryCache\3DA21691-E39D-4DA6-8A4B-B43877BCB1B7\*.xml %ProgramFiles%\Microsoft\OnlineManagement\PolicyAgent\ReportCache\3DA21691-E39D-4DA6-8A4B-B43877BCB1B7\*.xml %ProgramFiles%\microsoft policy platform\policyplatformclient*.log %TEMP%\clientui.log %Temp%\SoftwarePublishing\*.log %public%\Documents\MDMDiagnostics\* %windir%\scoconnector.etl %ProgramFiles%\Microsoft\OnlineManagement\Logs\* %ProgramFiles%\Microsoft\OnlineManagement\Updates\ReportingEvents.log %temp%\MSI*.* %windir%\temp\MSI*.* %ProgramFiles%\Microsoft Configuration Manager\logs\ndes* %ProgramFiles%\Microsoft Intune\NDESConnectorSvc\NDESConnector.exe.config %ProgramFiles%\Microsoft Intune\NDESConnectorSvc\logs\logs\* %ProgramFiles%\Microsoft Intune\NDESConnectorUI\Logs\* %ProgramFiles%\Microsoft Intune\NDESConnectorUI\NDESConnectorUI.log %ProgramFiles%\Microsoft Intune\NDESPolicyModule\Logs\NDESPlugin.log C:\NDESConnectorSetup\*.log C:\inetpub\logs\LogFiles\W3SVC1\u_ex*.log %windir%\Temp\OpsMgrTrace\*.* %LocalAppData%\mdm\*.log %ProgramData%\Microsoft\IntuneManagementExtension\Logs\* %systemroot%\system32\config\systemprofile\AppData\Local\mdm\*.log %systemroot%\TEMP\IntuneWindowsAgent_Proxy* %AppData%\Microsoft\Teams\*.txt %LocalAppData%\Microsoft\Teams\SquirrelSetup.log %LocalAppData%\Microsoft\Teams\current\SquirrelSetup.log %LocalAppData%\SquirrelTemp\* %windir%\system32\wbem\logs\*.* %windir%\system32\wbem\tmf\*.* %windir%\INF\*.log %windir%\windowsupdate*.log %windir%\logs\measuredboot\* C:\$Windows.~BT\Sources\Panther\* %windir%\system32\appraiser\appraiser.sdb HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TPM HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\CloudDomainJoin HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ProductOptions\ProductSuite HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows\CSDVersion HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CertPropSvc HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\crypt32 HKEY_LOCAL_MACHINE\SYSTEM\SYSTEM\CurrentControlSet\Services\CryptSvc HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HTTP\Parameters HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SCPolicySvc HKEY_LOCAL_MACHINE\HKLM\SYSTEM\CurrentControlSet\Services\SCardSvr HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\WindowsEmbedded\ProductVersion HKEY_CURRENT_USER\Software\Microsoft\SCEP HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Uninstall HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\BitLockerCsp HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\CCM HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\MSCEP HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DeviceManageabilityCSP HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DiagnosticLogCSP HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Enrollments HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\EnterpriseDesktopAppManagement HKEY_LOCAL_MACHINE\SOFTWARE\microsoft\enterprisemodernappmanagement HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\HVSICSP HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\IntuneManagementExtension HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MicrosoftIntune HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MicrosoftIntune HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft Operations Manager HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\multivariant HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\OfficeCSP HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\OnlineManagement HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\OnlineManagement\PolicyAgent HKEY_LOCAL_MACHINE\Software\Microsoft\POSReady HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Policies HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PolicyManager HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PolicyPlatform HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\provisioning HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Provisioning\Diagnostics\AutoPilot HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Provisioning\NodeCache\CSP HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SystemCenterAdvisor HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SystemCertificates\MY\Certificates HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SystemCertificates\System Center Online Client HKEY_LOCAL_MACHINE\Software\Microsoft\WEPOS\Version HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones HKEY_LOCAL_MACHINE\SOFTWARE\microsoft\windows\assignedaccessconfiguration HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\windows\assignedaccesscsp HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\Autopilot HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MDM HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Enrollments HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18 HKEY_LOCAL_MACHINE\Software\Policies HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Updates HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Policies\Microsoft\OnlineManagement\PolicyAgent HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\WindowsUpdate HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Policies\Microsoft\Microsoft Antimalware HKEY_CURRENT_USER\Software\Policies HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\EDPCSP HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\EnterpriseResourceManager HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Advanced Threat Protection HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Policies HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\BitLocker HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DmaSecurity HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Appraiser