test/AutopilotTestAttestation.psm1
<#PSScriptInfo
.VERSION 0.6 .GUID 715a6707-796c-445f-9e8a-8a0fffd778a5 .AUTHOR Rudy Ooms .COMPANYNAME .COPYRIGHT .TAGS Windows, AutoPilot, Powershell .LICENSEURI .PROJECTURI https://www.github.com .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .RELEASENOTES Version 0.1: Initial Release. Version 0.5: Changed to WMI and added some improvements. Version 0.6: Added some more checks .PRIVATEDATA #> <# .DESCRIPTION .SYNOPSIS GUI to import Device to Autopilot. MIT LICENSE Copyright (c) 2022 Rudy Ooms Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. .DESCRIPTION The goal of this script is to help with the troubleshooting of Attestation issues when enrolling your device with Autopilot for Pre-Provisioned deployments .EXAMPLE Blog post with examples and explanations @call4cloud.nl .LINK Online version: https://call4cloud.nl #> function Test-AutopilotAttestation { # Making sure the script is run as admin $currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent()) $runasadmin = $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) if($runasadmin -eq $false){ write-host "Script is not run as admin!" -ForegroundColor red exit (0) } # Test Internet Connection function Test-WebConnection { [CmdletBinding()] param ( [Parameter(ValueFromPipeline = $True)] [string]$Uri = 'google.com' ) begin {} process { $Params = @{ Method = 'Head' Uri = $Uri UseBasicParsing = $True } try { Write-Verbose "Test-WebConnection OK: $Uri" Invoke-WebRequest @Params | Out-Null $true } catch { Write-Verbose "Test-WebConnection FAIL: $Uri" $false } finally { $Error.Clear() } } end {} } $testinternernet = test-webconnection www.google.com If($testinternernet -eq "False"){ write-host "Internet Connection Available!" -ForegroundColor Green Write-Host @ErrorIcon } else { write-host "No Internet Connection Available, Please check your internet connection before trying again!" -ForegroundColor Red Write-Host @ErrorIcon exit 1 } if($internetmsg -eq "Internet Connection Available!"){ write-host "Making sure the correct Time is configured !" -ForegroundColor yellow If ((Get-Service W32Time).Status -eq "Running") { cmd /c "net stop w32time" | Out-Null } cmd /c "pushd %SystemRoot%\system32" | out-null cmd /c "net stop w32time" | out-null cmd /c "w32tm /unregister" | out-null cmd /c "w32tm /register" | out-null cmd /c "sc config w32time type= own" | out-null cmd /c "net start w32time" | out-null cmd /c "w32tm /config /update /manualpeerlist:0.pool.ntp.org,1.pool.ntp.org,2.pool.ntp.org,3.pool.ntp.org,0x8 /syncfromflags:MANUAL /reliable:yes" | out-null cmd /c "w32tm /resync" | out-null cmd /c "popd" | out-null # Apparaat Info $SerialNoRaw = wmic bios get serialnumber $SerialNo = $SerialNoRaw[2] $ManufacturerRaw = wmic computersystem get manufacturer $Manufacturer = $ManufacturerRaw[2] $ModelNoRaw = wmic computersystem get model $ModelNo = $ModelNoRaw[2] Write-Host "Computer Serialnumber: `t $SerialNo" -ForegroundColor Yellow Write-Host "Computer Supplier: `t $Manufacturer" -ForegroundColor Yellow Write-Host "Computer Model: `t $ModelNo" -ForegroundColor Yellow } Write-Host "Starting Connectivity test to Microsoft, Intel, Qualcomm and AMD" -ForegroundColor Yellow $TPM_ZTD = (Test-NetConnection ztd.dds.microsoft.com -Port 443).TcpTestSucceeded If ($TPM_ZTD -eq "True") { Write-Host -NoNewline -ForegroundColor Green "ZTD.DDS.Microsoft.Com - Success" Write-Host @ErrorIcon } Else { Write-Host -NoNewline -ForegroundColor Red "ZTD.DDS.Microsoft.com - Error" Write-Host @ErrorIcon } $TPM_Intel = (Test-NetConnection ekop.intel.com -Port 443).TcpTestSucceeded If($TPM_Intel -eq "True"){ Write-Host -NoNewline -ForegroundColor Green "TPM_Intel - Success " Write-Host @ErrorIcon } else { Write-Host -NoNewline -ForegroundColor Red "TPM_Intel - Error " Write-Host @ErrorIcon } $TPM_Qualcomm = (Test-NetConnection ekcert.spserv.microsoft.com -Port 443).TcpTestSucceeded If($TPM_Qualcomm -eq "True"){ Write-Host -NoNewline -ForegroundColor Green "TPM_Qualcomm - Success " Write-Host @ErrorIcon } else { Write-Host -NoNewline -ForegroundColor Red "TPM_Qualcomm - Error " Write-Host @ErrorIcon } $TPM_AMD = (Test-NetConnection ftpm.amd.com -Port 443).TcpTestSucceeded If($TPM_AMD -eq "True"){ Write-Host -NoNewline -ForegroundColor Green "TPM_AMD - Success " Write-Host @ErrorIcon } else { Write-Host -NoNewline -ForegroundColor Red "TPM_AMD - Error " Write-Host @ErrorIcon } $TPM_Azure = (Test-NetConnection azure.net -Port 443).TcpTestSucceeded If($TPM_Azure -eq "True"){ Write-Host -NoNewline -ForegroundColor Green "Azure - Success " Write-Host @ErrorIcon } else { Write-Host -NoNewline -ForegroundColor Red "Azure - Error " Write-Host @ErrorIcon } # Test Windows 10 license $WindowsProductKey = (Get-WmiObject -query "select * from SoftwareLicensingService").OA3xOriginalProductKey $WindowsProductType = (Get-WmiObject -query "select * from SoftwareLicensingService").OA3xOriginalProductKeyDescription Write-Host "[BIOS] Windows Product Key: $WindowsProductKey" -ForegroundColor Yellow Write-Host "[BIOS] Windows Product Type: $WindowsProductType" -ForegroundColor Yellow If($WindowsProductType -like "*Professional*" -or $WindowsProductType -eq "Windows 10 Pro" ){ Write-Host "BIOS Windows licentie is suited for MS365 enrollment" -ForegroundColor Green } else{ Write-Host "BIOS Windows licentie is not suited for MS365 enrollment" -ForegroundColor red $WindowsProductType = get-computerinfo | select WindowsProductName $WindowsProductType = $WindowsProductType.WindowsProductName Write-Host "[SOFTWARE] Windows Product Key: $WindowsProductKey" -ForegroundColor Yellow Write-Host "[SOFTWARE] Windows Product Type: $WindowsProductType" -ForegroundColor Yellow If($WindowsProductType -like "*Professional*" -or $WindowsProductType -eq "Windows 10 Pro" ){ Write-Host "SOFTWARE Windows licentie is valid for MS365 enrollment" -ForegroundColor Green } else{ Write-Host "SOFTWARE Windows licentie is not valid for MS365 Enrollment" -ForegroundColor red exit(0) } } # Test TPM Attestation # $IntegrityServicesRegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\IntegrityServices" $WBCL = "WBCL" $TaskStatesRegPath = "HKLM:\SYSTEM\CurrentControlSet\Services\TPM\WMI\taskStates" $EkCertificatePresent = "EkCertificatePresent" $OOBERegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\OOBE" $SetupDisplayedEula = "SetupDisplayedEula" # Downloading some additonial tpm tools --> not build in in windows10# $tpmtool = "https://call4cloud.nl/wp-content/uploads/2022/08/TpmDiagnostics.zip" $path = "C:\windows\system32" Invoke-WebRequest $tpmtool -OutFile "$path\ZippedFile.zip" Expand-Archive -LiteralPath "$path\ZippedFile.zip" -DestinationPath "$path" -force #testing ready for attestation with wmi instead of the get-tpm tool --> lanuage issues# write-host "Performing the Ready For attestation Test!" -ForegroundColor Yellow $attestation = Get-CimInstance -Namespace 'root/cimv2/Security/MicrosoftTpm' -ClassName 'Win32_TPM' | Invoke-CimMethod -MethodName 'Isreadyinformation' $attestationerror = $attestation.information $status = $attestation.information Write-Host "Determining if the TPM has vulnerable Firmware Part 1" -ForegroundColor Yellow $IfxManufacturerIdInt = 0x49465800 # 'IFX' function IsInfineonFirmwareVersionAffected ($FirmwareVersion) { $FirmwareMajor = $FirmwareVersion[0] $FirmwareMinor = $FirmwareVersion[1] switch ($FirmwareMajor) { 4 { return $FirmwareMinor -le 33 -or ($FirmwareMinor -ge 40 -and $FirmwareMinor -le 42) } 5 { return $FirmwareMinor -le 61 } 6 { return $FirmwareMinor -le 42 } 7 { return $FirmwareMinor -le 61 } 133 { return $FirmwareMinor -le 32 } default { return $False } } } function IsInfineonFirmwareVersionSusceptible ($FirmwareMajor) { switch ($FirmwareMajor) { 4 { return $True } 5 { return $True } 6 { return $True } 7 { return $True } 133 { return $True } default { return $False } } } $Tpm = Get-Tpm $ManufacturerIdInt = $Tpm.ManufacturerId $FirmwareVersion = $Tpm.ManufacturerVersion -split "\." $FirmwareVersionAtLastProvision = (Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\TPM\WMI" -Name "FirmwareVersionAtLastProvision" -ErrorAction SilentlyContinue).FirmwareVersionAtLastProvision if (!$Tpm) { Write-Host "No TPM found on this system, so the issue does not apply here." } else { if ($ManufacturerIdInt -ne $IfxManufacturerIdInt) { Write-Host "This non-Infineon TPM is not affected by the issue." } else { if ($FirmwareVersion.Length -lt 2) { Write-Error "Could not get TPM firmware version from this TPM." } else { if (IsInfineonFirmwareVersionSusceptible($FirmwareVersion[0])) { if (IsInfineonFirmwareVersionAffected($FirmwareVersion)) { Write-Host ("This Infineon firmware version {0}.{1} TPM is not safe. Please update your firmware." -f [int]$FirmwareVersion[0], [int]$FirmwareVersion[1]) -ForegroundColor red } else { Write-Host ("This Infineon firmware version {0}.{1} TPM is safe." -f [int]$FirmwareVersion[0], [int]$FirmwareVersion[1]) -ForegroundColor green if (!$FirmwareVersionAtLastProvision) { Write-Host ("We cannot determine what the firmware version was when the TPM was last cleared. Please clear your TPM now that the firmware is safe.") -ForegroundColor red } elseif ($FirmwareVersion -ne $FirmwareVersionAtLastProvision) { Write-Host ("The firmware version when the TPM was last cleared was different from the current firmware version. Please clear your TPM now that the firmware is safe.") -ForegroundColor yellow } } } else { Write-Host ("This Infineon firmware version {0}.{1} TPM is safe." -f [int]$FirmwareVersion[0], [int]$FirmwareVersion[1]) -ForegroundColor green } } } } if($attestationerror -eq "0") { write-host "TPM seems Ready For Attestation.. Let's Continue and test the Attestation itself!" -ForegroundColor Green } if(!(Get-Tpm | Select-Object tpmowned).TpmOwned -eq $true) { Write-Host "Reason: TpmOwned is FALSE (Get-Tpm)" -ForegroundColor Red } if($attestationerror -eq "16777216") { write-host "The TPM has a Health Attestation related vulnerability, please update your TPM firmware!" -ForegroundColor red } If(!(Get-ItemProperty -Path $IntegrityServicesRegPath -Name $WBCL -ErrorAction Ignore)) { Write-Host "Reason: Registervalue HKLM:\SYSTEM\CurrentControlSet\Control\IntegrityServices\WBCL does not exist! Measured boot logs are missing. Make sure your reboot your device!" -ForegroundColor Red } if(((Get-ItemProperty -Path $TaskStatesRegPath | Out-null).EkCertificatePresent -ne 1 ) -or ($attestationerror -eq "262144")) { Write-Host "Reason: Registervalue HKLM:\SYSTEM\CurrentControlSet\Services\TPM\WMI\taskStates\EkCertificatePresent missing!! Launching TPM-Maintenance Task!" -ForegroundColor Red Start-ScheduledTask -TaskPath "\Microsoft\Windows\TPM\" -TaskName "Tpm-Maintenance" -erroraction 'silentlycontinue' sleep 5 $taskinfo = Get-ScheduledTaskInfo -TaskName "\Microsoft\Windows\TPM\Tpm-Maintenance" -ErrorAction Ignore $tasklastruntime = $taskinfo.LastTaskResult If($tasklastruntime -ne 0) { Write-Host "Reason: TPM-Maintenance Task could not be run! Checking and Configuring the EULA Key!" -ForegroundColor Red } If((!(Get-ItemProperty -Path $OOBERegPath -Name $SetupDisplayedEula -ErrorAction Ignore)) -or ((Get-ItemProperty -Path $OOBERegPath -Name $SetupDisplayedEula -ErrorAction Ignore).SetupDisplayedEula -ne 1)) { Write-Host "Reason: Registervalue HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\OOBE\SetupDisplayedEula does not exist! EULA is not accepted!" -ForegroundColor Red New-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\OOBE\' -Name 'SetupDisplayedEula' -Value '1' -PropertyType 'DWORD' –Force| Out-null Write-Host "SetupDisplayedEula registry key configured, rerunning the TPM-Maintanence Task" -ForegroundColor Yellow Start-ScheduledTask -TaskPath "\Microsoft\Windows\TPM\" -TaskName "Tpm-Maintenance" -erroraction 'silentlycontinue' } sleep 5 $taskinfo = Get-ScheduledTaskInfo -TaskName "\Microsoft\Windows\TPM\Tpm-Maintenance" -ErrorAction Ignore $tasklastruntime = $taskinfo.LastTaskResult If($tasklastruntime -ne 0) { Write-Host "TPM-Maintenance task could not be run succesfully despite the EULA key being set! Exiting now!" -ForegroundColor Red exit (0) } If($tasklastruntime -eq 0) { Write-Host "EULA Key is set and TPM-Maintenance Task has been run succesfully!" -ForegroundColor Green } } if(!(test-path -path HKLM:\SYSTEM\CurrentControlSet\Services\Tpm\WMI\Endorsement\EKCertStore\Certificates\*)) { Write-Host "Reason:EKCert seems to be missing in HKLM:\SYSTEM\CurrentControlSet\Services\Tpm\WMI\Endorsement\EKCertStore\Certificates\ - Launching TPM-Maintenance Task!" -ForegroundColor Red Start-ScheduledTask -TaskPath "\Microsoft\Windows\TPM\" -TaskName "Tpm-Maintenance" -erroraction 'silentlycontinue' sleep 5 Write-Host "Going hardcore! Installing that damn EkCert on our own!!" -ForegroundColor yellow tpmdiagnostics installekcertfromnvr | out-null tpmdiagnostics installekcertfromweb | out-null tpmdiagnostics installekcertThroughCoreProv | out-null sleep 5 $endorsementkey = get-tpmendorsementkeyinfo } if($endorsementkey.IsPresent -ne $true) { Write-Host "Endorsementkey still not present!!" -ForegroundColor Red }else { Write-Host "Endorsementkey reporting for duty!" -ForegroundColor green } #geting AIK Test CertEnroll error $attestation = Get-CimInstance -Namespace 'root/cimv2/Security/MicrosoftTpm' -ClassName 'Win32_TPM' | Invoke-CimMethod -MethodName 'Isreadyinformation' $attestationerror = $attestation.information if($attestationerror -eq "0") { write-host "Retrieving AIK Certificate....." -ForegroundColor Green $errorcert = 1 for($num = 1 ; $errorcert -ne -1 ; $num++) { Write-Host "Fetching test-AIK cert - attempt $num" $certcmd = (cmd.exe /c "certreq -q -enrollaik -config """) $startcert = [array]::indexof($certcmd,"-----BEGIN CERTIFICATE-----") $endcert = [array]::indexof($certcmd,"-----END CERTIFICATE-----") $errorcert = [array]::indexof($certcmd,'{"Message":"Failed to parse SCEP request."}') $certlength = $endcert - $startcert If($certlength -gt 1){ write-host "Found Test AIK Certificate" -ForegroundColor Green $cert = $certcmd[$startcert..$endcert] write-host $cert -ForegroundColor DarkGreen write-host "AIK Test AIK Enrollment succeeded" -ForegroundColor Green } else{ write-host "Determing if the AIK Url is available" -ForegroundColor yellow $Cacapserror = $CERTCMD -like "*GetCACaps: Not Found*" if ($CaCapserror) { Write-Host "AIK CA Url is not valid" -ForegroundColor Red }else{ Write-Host "AIK Url is valid" -ForegroundColor Green } write-host "AIK TEST Certificaat could not be retrieved" -ForegroundColor Red if($num -eq 10) { write-host "Retried 10 times, killing process" -ForegroundColor Red exit (0) } } } #fetching AIkCertEnrollError Write-Host "Running another test, to determine if the TPM is capable for key attestation... just for fun!!" -ForegroundColor Yellow $attestationcapable = Get-CimInstance -Namespace 'root/cimv2/Security/MicrosoftTpm' -ClassName 'Win32_TPM' | Invoke-CimMethod -MethodName 'IsKeyAttestationCapable' $attestationcapable = $attestationcapable.testresult If ($attestationcapable -ne 0){ Write-Host "Reason: TPM doesn't seems capable for Attestation!" -ForegroundColor Red tpmtool getdeviceinformation }else{ Write-Host "We can almost start celebrating! Because the TPM is capable for attestation! "-ForegroundColor green } Write-Host "Launching the real AikCertEnroll task!" -ForegroundColor Yellow Start-ScheduledTask -TaskPath "\Microsoft\Windows\CertificateServicesClient\" -TaskName "AikCertEnrollTask" sleep 5 $AIKError = "HKLM:\SYSTEM\CurrentControlSet\Control\Cryptography\Ngc\AIKCertEnroll\" If ((Get-ItemProperty -Path $AIKError -Name "ErrorCode" -ErrorAction Ignore).errorcode -ne 0) { Write-Host "Reason: AIK Cert Enroll Failed!" -ForegroundColor Red tpmtool getdeviceinformation }else{ Write-Host "AIK Cert Enroll Task Succeeded, Looks like the device is 100% ready for attestation!You can start the Autopilot Pre-Provioning! "-ForegroundColor green } }else{ write-host "TPM is still NOT suited for Autopilot Pre-Provisioning, please re-run the test again" -ForegroundColor RED tpmtool getdeviceinformation exit (0) } } |