Validate-NewIntuneNDESConfig.ps1


<#PSScriptInfo
 
.VERSION 1.0
 
.GUID f4f1a062-5425-4ace-a47d-5604c1ba7be0
 
.AUTHOR Leon Zhu, Premkumar N
 
.COMPANYNAME
 
.COPYRIGHT
 
.TAGS
 
.LICENSEURI
 
.PROJECTURI
 
.ICONURI
 
.EXTERNALMODULEDEPENDENCIES
 
.REQUIREDSCRIPTS
 
.EXTERNALSCRIPTDEPENDENCIES
 
.RELEASENOTES
Version 1.0:
 
#>


<#
 
.DESCRIPTION
Since Intune has released new certificate connector and way to issue SCEP cert from NDES server. This script will up way to check configuration on NDES based on previous Validate-NDESConfig, and ensures it aligns to the "Configure and manage SCEP
certificates with new Intune certification connector. This is based on https://github.com/microsoftgraph/powershell-intune-samples/blob/master/CertificationAuthority/Validate-NDESConfiguration.ps1
 
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 will be provided.
 
Validates and highlights configuration problems on an NDES server installed new Intune certificate connector。
 
Use of this script requires the following:
 
Script should be ran directly on the NDES Server
Requires PowerShell version 3.0 at a minimum
Requires PowerShell to be Run As Administrator
 
Re-write
Check Server version
Check NDES role and CA status
Check SCEP in IIS application pool
Add certificate valid check for MSCEP and connector certificate
Add new feature to check Connector event log
 
#>
 

Param(
[parameter(ParameterSetName="Help")]
[alias("h","?","/?")]
[switch]$help,

[parameter(ParameterSetName="Help")]
[alias("u")]
[switch]$usage  
)
    
#######################################################################

Function Log-ScriptEvent{
    
    [CmdletBinding()]
    
    Param(
      [parameter(Mandatory=$True)]
      [String]$LogFilePath,

      [parameter(Mandatory=$True)]
      [String]$Value,

      [parameter(Mandatory=$True)]
      [String]$Component,

      [parameter(Mandatory=$True)]
      [ValidateRange(1,3)]
      [Single]$Severity
      )

        $DateTime = New-Object -ComObject WbemScripting.SWbemDateTime 
        $DateTime.SetVarDate($(Get-Date))
        $UtcValue = $DateTime.Value
        $UtcOffset = $UtcValue.Substring(21, $UtcValue.Length - 21)

        $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=`"`">"

        Add-Content -Path $LogFilePath -Value $LogLine

}

##########################################################################################################

function Show-Usage {

    Write-Host
    Write-Host "-help -h Displays the help."
    Write-Host "-usage -u Displays this usage information."
    Write-Host

}

#######################################################################

function Get-NDESHelp {

    Write-Host
    Write-Host "Verifies if the NDES server meets the required configuration for new Intune certificate connector. "
    Write-Host
    Write-Host "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-Host "See https://learn.microsoft.com/en-us/mem/intune/protect/certificates-scep-configure."
    Write-Host "The script will check "
    Write-Host
   

}

#######################################################################

    if ($help){

        Get-NDESHelp
        break

    }

    if ($usage){

        Show-Usage
        break
    }

#######################################################################

#Requires -version 3.0
#Requires -RunAsAdministrator

#######################################################################

$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-NewIntuneNDESConfig.log"

#######################################################################
Write-host "##########################################################################################"
Write-Host "## ##"
Write-Host "## You are using new Intune NDES vertification script. ##"
Write-Host "## This script is used purely to validate the configuration. ##"
Write-Host "## All remedial tasks will need to be carried out manually.. ##"
Write-Host "## ##"
Write-host "##########################################################################################"
Write-Host
Write-Host
Write-Host "Would you like to procee with variables? [Y]es, [N]o" -ForegroundColor Cyan
    
$confirmation = Read-Host

if ($confirmation -eq 'y'){
    
    Write-Host
    Write-host "Starting validation job" -ForegroundColor Cyan -NoNewline
    Write-Host "..............................."
    Log-ScriptEvent $LogFilePath "Initializing log file $($TempDirPath)\Validate-NDESConfig.log"  NDES_Validation 1
    Log-ScriptEvent $LogFilePath "Proceeding with variables=YES"  NDES_Validation 1

#######################################################################

#region checking Server OS version
Write-host
Write-host "......................................................."
Write-host
Write-host "Checking Current Server OS version..." -ForegroundColor Yellow
Write-host
Log-ScriptEvent $LogFilePath "Checking OS Version" NDES_Validation 1
$OSVersion = (Get-CimInstance -class Win32_OperatingSystem).Version

#Require version requires 2012 R2 and above
$MinOSVersion = "6.3.9600"

if ([version]$OSVersion -lt [version]$MinOSVersion){

    Write-host "Error: Unsupported OS Version. NDES Requires 2012 R2 and above." -BackgroundColor Red
    Log-ScriptEvent $LogFilePath "Unsupported OS Version. NDES Server Requires 2012 R2 and above. Server version is $($OSVersion)" NDES_Validation 3
    
    } 
else {

    Write-Host "Success: " -ForegroundColor Green -NoNewline
    Write-Host "OS Version " -NoNewline
    write-host "$($OSVersion)" -NoNewline -ForegroundColor Cyan
    write-host " meet prerequisites."
    Log-ScriptEvent $LogFilePath "Success: Server version is $($OSVersion)" NDES_Validation 1

}

Log-ScriptEvent $LogFilePath "*********************************************************************************"  NDES_Validation 3
#endregion

#######################################################################

#region Checking if NDES server is the CA and NDES install

Write-host "`n.......................................................`n"
Write-host "Checking if NDES server is the CA...`n" -ForegroundColor Yellow
Log-ScriptEvent $LogFilePath "Checking if NDES server is the CA" NDES_Validation 1


# Check if Certification Authority is installed
$caRole = (Get-WindowsFeature -Name ADCS-Cert-Authority -ErrorAction SilentlyContinue).InstallState

# Check if Network Device Enrollment Service is installed
$ndeRole = (Get-WindowsFeature -Name ADCS-Device-Enrollment -ErrorAction SilentlyContinue).InstallState

if ($caRole -ne "Installed" -and $ndeRole -eq "Installed") {

    Write-Host "Success: " -ForegroundColor Green -NoNewline
    Write-Host "The server has the 'Network Device Enrollment Service' role installed but does not have the 'Certification Authority' role installed." 
    Log-ScriptEvent $LogFilePath "Success: The server has the 'Network Device Enrollment Service' role installed but does not have the 'Certification Authority' role installed." NDES_Validation 1

} elseif ($caRole -eq "Installed") {

    Write-Host "Error: " -ForegroundColor Red -NoNewline
    Write-Host "NDES server has Certification Authority Role installed. This is an unsupported configuration!" 
    Log-ScriptEvent $LogFilePath "Error: NDES server has Certification Authority Role installed. This is an unsupported configuration!" NDES_Validation 3

} elseif ($ndeRole -ne "Installed") {

    Write-Host "Error: " -ForegroundColor Red -NoNewline
    Write-Host "The server does not have 'Network Device Enrollment Service' role installed."
    Log-ScriptEvent $LogFilePath "Error:The server does not have 'Network Device Enrollment Service' role installed." NDES_Validation 3


} else {

    Write-Host "Error: " -ForegroundColor Red -NoNewline
    Write-Host "The server does not have 'Network Device Enrollment Service' role installed." 
    Log-ScriptEvent $LogFilePath "Error:The server does not have 'Network Device Enrollment Service' role installed." NDES_Validation 3
}
Log-ScriptEvent $LogFilePath "*********************************************************************************"  NDES_Validation 3

#endregion

#######################################################################

#region Define the server roles and prerequest features to check
Write-host
Write-host "......................................................."
Write-host
Write-host "Checking if NDES server has installed required features`n" -ForegroundColor Yellow
Log-ScriptEvent $LogFilePath "Checking if NDES server has installed required features" NDES_Validation 1 

$requiredRolesAndFeatures = @(
                                "AD-Certificate", # Active Directory Certificate Services
                                "Web-Server", # Web Server (IIS)
                                "NET-Framework-45-Features", # Assuming .NET Framework 4.5 Features as a placeholder for .NET 4.7
                                "Web-Asp-Net45", # Assuming ASP.NET 4.5 as a placeholder for ASP.NET 4.7
                                "NET-WCF-HTTP-Activation45" # HTTP Activation
                            )

# Checking each role and feature
foreach ($feature in $requiredRolesAndFeatures) {
    $status = Get-WindowsFeature -Name $feature
    
    if ($status.Installed) {
        
        Write-Host "Success: " -ForegroundColor Green -NoNewline
        write-host "$($status.DisplayName)" -NoNewline -ForegroundColor Cyan
        Write-Host " is installed."
        Log-ScriptEvent $LogFilePath "$($status.DisplayName) is installed." NDES_Validation 1 

    } else {

        Write-Host "Error: " -ForegroundColor Red -NoNewline
        write-host "$($status.DisplayName)" -NoNewline -ForegroundColor DarkCyan
        Write-Host " is not installed."
        Log-ScriptEvent $LogFilePath "Error: $($status.DisplayName) is not installed." NDES_Validation 3

    }
}

# Additional check for .NET Framework 4.7 - This is a simplified approach
# You might need a more specific check depending on your requirements
$dotNet47Key = "HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full"

if ((Get-ItemProperty -Path $dotNet47Key -Name Release).Release -ge 460798) {
    
    Write-Host "Success: " -ForegroundColor Green -NoNewline
    Write-Host ".NET Framework 4.7 or later is installed." 
    Log-ScriptEvent $LogFilePath "Success: .NET Framework 4.7 or later is installed." NDES_Validation 1 

} else {

    Write-Host "Error: " -ForegroundColor Red -NoNewline
    Write-Host ".NET Framework 4.7 or later is not installed." 
    Log-ScriptEvent $LogFilePath ".NET Framework 4.7 or later is not installed." NDES_Validation 1 

}
Log-ScriptEvent $LogFilePath "*********************************************************************************"  NDES_Validation 3
#endregion

#######################################################################

################################################################
#The detection way is not good and need to improve
################################################################

#region Checking NDES Install Paramaters
Write-host
Write-host "......................................................."
Write-host
Write-host "Checking if NDES Configured paramters correctly`n" -ForegroundColor Yellow
Log-ScriptEvent $LogFilePath "Checking if NDES Configured paramters correctly" NDES_Validation 1 

# Specify the registry path for the NDES CSP
$ndesCspRegPath = "HKLM:\SOFTWARE\Microsoft\Cryptography\Defaults\Provider\Microsoft Strong Cryptographic Provider"

# Check if the registry path exists
if (Test-Path $ndesCspRegPath) {

    Write-Host "Success: " -ForegroundColor Green -NoNewline
    Write-Host "The NDES server is using the correct signature provider." 
    Log-ScriptEvent $LogFilePath "Success: The NDES server is using the correct signature provider." NDES_Validation 1 


} else {

    Write-Host "Error: " -ForegroundColor Red -NoNewline
    Write-Host "Warning: The NDES server is not using the correct signature provider." 
    Log-ScriptEvent $LogFilePath "The NDES server is not using the correct signature provider." NDES_Validation 3
}
Log-ScriptEvent $LogFilePath "*********************************************************************************"  NDES_Validation 3
#endregion

#################################################################

#region Check SCEP Application is running in IIS (Need admin permission)
Write-host
Write-host "......................................................."
Write-host
Write-host "Checking if SCEP Application is running in IIS `n" -ForegroundColor Yellow
Log-ScriptEvent $LogFilePath "Checking if SCEP Application is running in IIS " NDES_Validation 1 

# Define the name of the application pool you want to check
$appPoolName = "SCEP"

# Use appcmd.exe to list the application pool and find its state
$appCmdPath = "${env:SystemRoot}\system32\inetsrv\appcmd.exe"
$command = "& `"$appCmdPath`" list apppool /name:`"$appPoolName`" /text:state"

try {

    $appPoolState = Invoke-Expression $command
    
    if ($appPoolState -eq "Started") {

        Write-Host "Success: " -ForegroundColor Green -NoNewline
        Write-Host "The application pool " -NoNewline 
        write-host "$($appPoolName)" -NoNewline -ForegroundColor Cyan
        Write-Host " is running." 
        Log-ScriptEvent $LogFilePath "Success: The application pool '$appPoolName' is running." NDES_Validation 1 
    
    } elseif ($appPoolState -eq "Stopped") { 

        Write-Host "Error: " -ForegroundColor Red -NoNewline
        Write-Host "The application pool " -NoNewline 
        write-host "$($appPoolName)" -NoNewline -ForegroundColor DarkCyan
        Write-Host " is stop." 
        Log-ScriptEvent $LogFilePath "The application pool '$appPoolName' is stopped." NDES_Validation 3 
    
    } else {


        Write-Host "Error: " -ForegroundColor Red -NoNewline
        Write-Host "The application pool " -NoNewline 
        write-host "$($appPoolName)" -NoNewline -ForegroundColor DarkCyan
        Write-Host " is in an unknown state:" -NoNewline
        Write-Host "$($appPoolState)" -BackgroundColor Red
        Log-ScriptEvent $LogFilePath "The application pool '$appPoolName' is in an unknown state: $appPoolState" NDES_Validation 3
    
    }
} catch {
    
    Write-Host "An error occurred while checking the application pool status. Error: $_" -ForegroundColor Red
    Log-ScriptEvent $LogFilePath "An error occurred while checking the application pool status. Error: $_" NDES_Validation 3

}
Log-ScriptEvent $LogFilePath "*********************************************************************************"  NDES_Validation 3
#endregion

#######################################################################

#region Checking the EnrollmentAgentOffline and CEPEncryption are present and still valid

$ErrorActionPreference = "Silentlycontinue"

Write-host
Write-host "......................................................."
Write-host
Write-Host "Checking the EnrollmentAgentOffline and CEPEncryption are present..." -ForegroundColor Yellow
Write-host
Log-ScriptEvent $LogFilePath "Checking the MSCEP certificates of EnrollmentAgentOffline and CEPEncryption are present and valid" NDES_Validation 1

$certs = Get-ChildItem cert:\LocalMachine\My\

#get current time
$currentDate = Get-Date

# Looping through all certificates in LocalMachine Store
Foreach ($item in $certs){

    $Output = ($item.Extensions| where-object {$_.oid.FriendlyName -like "**"}).format(0).split(",")
    $expirationDate = $item.NotAfter

    if (($Output -match "EnrollmentAgentOffline") -and ($expirationDate -gt $currentDate)){
    
        $EnrollmentAgentOffline = $TRUE
        $EnrollmentAgentOfflineNotAfter = $expirationDate
    
    }
        
    if (($Output -match "CEPEncryption") -and ($expirationDate -gt $currentDate)){
        
        $CEPEncryption = $TRUE
        $CEPEncryptionNotAfter = $expirationDate
        
    }

} 


# Checking if EnrollmentAgentOffline certificate is present
if ($EnrollmentAgentOffline){

    Write-Host "Success: " -ForegroundColor Green -NoNewline
    Write-Host "EnrollmentAgentOffline certificate is present and valid till: " -NoNewline
    write-host "$($EnrollmentAgentOfflineNotAfter)"  -ForegroundColor Cyan
    Log-ScriptEvent $LogFilePath "Success: EnrollmentAgentOffline certificate is present and valid"  NDES_Validation 1

} else {

    Write-Host "Error: " -ForegroundColor Red -NoNewline
    Write-Host "EnrollmentAgentOffline certificate is not present or expired !" 
    Write-Host "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." 
    Log-ScriptEvent $LogFilePath "EnrollmentAgentOffline certificate is not present or expired"  NDES_Validation 3 

}

# Checking if CEPEncryption is present
if ($CEPEncryption){
    
    Write-Host "Success: " -ForegroundColor Green -NoNewline
    Write-Host "CEPEncryption is present and valid till: " -NoNewline
    Write-Host "$($CEPEncryptionNotAfter)" -ForegroundColor Cyan  
    Log-ScriptEvent $LogFilePath "CEPEncryption certificate is present and valid"  NDES_Validation 1
    
} else {

    Write-Host "Error: " -ForegroundColor Red -NoNewline
    Write-Host "CEPEncryption certificate is not present or expired!" -BackgroundColor red 
    Write-Host "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." 
    Log-ScriptEvent $LogFilePath "Success: CEPEncryption certificate is not present or expired!"  NDES_Validation 3
    
}
Log-ScriptEvent $LogFilePath "*********************************************************************************"  NDES_Validation 3

$ErrorActionPreference = "Continue"

#endregion

#################################################################

#region Checking registry has been set with the SCEP certificate template name

Write-host
Write-host "......................................................."
Write-host
Write-Host 'Checking registry "HKLM:SOFTWARE\Microsoft\Cryptography\MSCEP" has been set with the SCEP certificate template name...' -ForegroundColor Yellow
Write-host
Log-ScriptEvent $LogFilePath "Checking if 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-host "Error: " -ForegroundColor Red -NoNewline
    Write-host "Registry key does not exist. This can occur if the NDES role has been installed but not configured." 
    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-host "Error: " -ForegroundColor Red -NoNewline
                Write-Host "Registry has not been configured with the SCEP Certificate template name. Default values have _not_ been changed." 
                Write-Host
                Log-ScriptEvent $LogFilePath "Registry has not been configured with the SCEP Certificate template name. Default values have _not_ been changed."  NDES_Validation 3
            
            } else {

                Write-Host "One or more default values have been changed."
                Write-Host 
                write-host "Checking key..."
                Write-host
                write-host "Signature template value: " -NoNewline
                Write-host "$($SignatureTemplate)" -ForegroundColor Cyan
                write-host "Encryption template value: " -NoNewline
                Write-host "$($EncryptionTemplate)" -ForegroundColor Cyan
                write-host "GeneralPurpose template value: " -NoNewline
                Write-host "$($GeneralPurposeTemplate)" -ForegroundColor Cyan
                Log-ScriptEvent $LogFilePath "Signature template value: $($SignatureTemplate)" NDES_Validation 1
                Log-ScriptEvent $LogFilePath "Encryption template value: $($EncryptionTemplate)" NDES_Validation 1
                Log-ScriptEvent $LogFilePath "GeneralPurpose template value: $($GeneralPurposeTemplate)" NDES_Validation 1

            }
}
Log-ScriptEvent $LogFilePath "*********************************************************************************"  NDES_Validation 3  
$ErrorActionPreference = "Continue"

#endregion

#################################################################

#region Checking Intune Connector is installed

Write-host
Write-host "......................................................."
Write-host
Write-Host "Checking Intune Connector is installed..." -ForegroundColor Yellow
Write-host
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 | Where-Object {$_.DisplayName -eq "Certificate Connector for Microsoft Intune"}){

    Write-Host "Success: " -ForegroundColor Green -NoNewline
    Write-Host "$($IntuneConnector.DisplayName) was installed on " -NoNewline 
    Write-Host "$($IntuneConnector.InstallDate)" -ForegroundColor Cyan -NoNewline 
    write-host "and is version " -NoNewline
    Write-Host "$($IntuneConnector.DisplayVersion)" -ForegroundColor Cyan -NoNewline
    Write-host
    Log-ScriptEvent $LogFilePath "Connector installed and ConnectorVersion:$IntuneConnector"  NDES_Validation 1

} else {

    Write-host "Error: " -ForegroundColor Red -NoNewline
    Write-Host "Intune Connector not installed" 
    Log-ScriptEvent $LogFilePath "ConnectorNotInstalled"  NDES_Validation 3 
    
}
Log-ScriptEvent $LogFilePath "*********************************************************************************"  NDES_Validation 3
#endregion

#################################################################

#region Checking Intune Connector registry keys and check if connector certificate is vaild.

Write-host
Write-host "......................................................."
Write-host
Write-Host "Checking Intune Connector registry keys are intact" -ForegroundColor Yellow
Write-host
Log-ScriptEvent $LogFilePath "Checking Intune Connector registry keys are intact and certificate" NDES_Validation 1

$ErrorActionPreference = "SilentlyContinue"
$connectorPath = "HKLM:SOFTWARE\Microsoft\MicrosoftIntune\PFXCertificateConnector"

if (-not (Test-Path $connectorPath)){
    
    Write-host "Error: Connector Registry key does not exist. Connector didn't install" -BackgroundColor Red
    Log-ScriptEvent $LogFilePath "Connector Registry key does not exist. Connecotr didn't configure"  NDES_Validation 3 

} else {
    
    $EncryptionCertThumbprint = (Get-ItemProperty -Path $connectorPath -Name EncryptionCertThumbprint).EncryptionCertThumbprint
    
    if (-not ($EncryptionCertThumbprint)){
        
        Write-host "Error: " -ForegroundColor Red -NoNewline
        Write-host "EncryptionCertThumbprint Registry key does not exist. Connector didn't finish configuration" 
        Log-ScriptEvent $LogFilePath "EncryptionCertThumbprint Registry key does not exist. Connecotr didn't configure"  NDES_Validation 3 
    
    } else {

        # Get the certificate from the Personal certificate store
          $Connectorcert = Get-ChildItem -Path cert:\LocalMachine\My\ -Recurse | Where-Object {$_.Thumbprint -eq $EncryptionCertThumbprint}
          #get current time
          $currentDate = Get-Date

         #Connector certificate still valid
        if ($Connectorcert) {
            Write-Host "Certificate found:"
            Write-Host "Subject : "  -NoNewline
            Write-Host $Connectorcert.Subject -ForegroundColor Cyan 
            Write-Host "Issuer : "  -NoNewline
            Write-Host $Connectorcert.Issuer -ForegroundColor Cyan 
            Write-Host "Thumbprint : "  -NoNewline
            Write-Host $Connectorcert.Thumbprint -ForegroundColor Cyan
            Write-Host "Valid From : "  -NoNewline
            Write-Host $Connectorcert.NotBefore -ForegroundColor Cyan 
            Write-Host "Valid To : "  -NoNewline
            Write-Host $Connectorcert.NotAfter -ForegroundColor Cyan 

            if ($Connectorcert.NotAfter -gt $currentDate){
            
             Write-Host "Certificate is valid:"  -NoNewline
             Write-Host $Connectorcert.NotAfter -ForegroundColor Cyan
             Log-ScriptEvent $LogFilePath "Certificate $($Connectorcert.Subject) is valid: $($Connectorcert.NotAfter)"  NDES_Validation 1 

            
            }
            else{
                
              Write-host "Error: " -ForegroundColor Red -NoNewline
              Write-Host "Conncetor Certificate is expired and we need to renew cert:"
              Write-Host "Valid To: " -NoNewline
              Write-Host $Connectorcert.NotAfter -ForegroundColor Red
              Write-Host "You can delete exipred cert in store and sign-in connector again" 
              Log-ScriptEvent $LogFilePath "Conncer Certificate is expired at $($Connectorcert.NotAfter) and we need to renew cert:"  NDES_Validation 3 
          
            }

        } else  {
            Write-Host "Certificate with thumbprint $EncryptionCertThumbprint not found in the Personal certificate store."
            Log-ScriptEvent $LogFilePath "Certificate with thumbprint $EncryptionCertThumbprint not found in the Personal certificate store."  NDES_Validation 3 
        }        
    }
}

$ErrorActionPreference = "Continue"
Log-ScriptEvent $LogFilePath "*********************************************************************************"  NDES_Validation 3
#endregion

#################################################################

#region Checking behaviour of internal NDES URL

$hostname = ([System.Net.Dns]::GetHostByName(($env:computerName))).hostname
Write-host
Write-host "......................................................."
Write-host
Write-Host "Checking behaviour of internal NDES URL: " -NoNewline -ForegroundColor Yellow
Write-Host "https://$hostname/certsrv/mscep/mscep.dll" -ForegroundColor Cyan
Write-host
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-host "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." -BackgroundColor Red
    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-Host "Trying to retrieve CA Capabilitiess..." -ForegroundColor Yellow
    Write-Host
    
    $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-Host "Success: " -ForegroundColor Green -NoNewline
        write-host "CA Capabilities retrieved:"
        Write-Host
        write-host $CACaps
        Log-ScriptEvent $LogFilePath "CA Capabilities retrieved:$CACaps"  NDES_Validation 1
            
        }

}else {

    Write-host "Error: Unexpected Error code! This usually signifies an error with the Intune Connector registering itself or not being installed" -BackgroundColor Red
    Write-host "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

}
Log-ScriptEvent $LogFilePath "*********************************************************************************"  NDES_Validation 3
#endregion


#################################################################

#This part will be improved to show more detials based on Error message
#region Checking eventlog for pertinent errors https://learn.microsoft.com/en-us/mem/intune/protect/certificate-connector-overview

Write-host
Write-host "......................................................."
Write-host
Write-Host "Checking Error logs in Event Viewer for last 2 days" -ForegroundColor Yellow
Log-ScriptEvent $LogFilePath "Checking Event log for connector" NDES_Validation 1

$ErrorActionPreference = "SilentlyContinue"

# Define the log name and time frame
$ConnectorlogAdmin = "Microsoft-Intune-CertificateConnectors/Admin"

$ConnectorlogOperational = "Microsoft-Intune-CertificateConnectors/Operational"

#check last 20 days event log
$EventstartTime = (Get-Date).AddDays(-2)

# Get the error events from the intune connector Admin log and check error.
$errorEventsAdminLog = Get-WinEvent -FilterHashtable @{LogName=$ConnectorlogAdmin;StartTime=$EventstartTime;ID='1001','1201','2001','3001','4001','4002'} -MaxEvents 5 -ErrorAction SilentlyContinue

# Display the error events in Admin
if ($errorEventsAdminLog) {
    
    write-host "Errors found in the Microsoft Intune Connector Admin Event log" -BackgroundColor Red
    write-host "List first 5 errors in the Microsoft Intune Connector Admin Event log" -BackgroundColor Red
    Log-ScriptEvent $LogFilePath "Errors found in the Microsoft Intune Connector Admin Event log" NDES_Validation 3
    Log-ScriptEvent $LogFilePath "List first 5 errors in the Microsoft Intune Connector Admin Event log" NDES_Validation 3

    foreach ($event in $errorEventsAdminLog) {
        
        $Time = $event.TimeCreated
        $ID = $event.Id
        $Message = $event.Message
    
        Write-Host "......................................................."
        Write-Host "Event Time: "-NoNewline
        Write-Host $Time -ForegroundColor Cyan
        Write-Host "EVent ID: " -NoNewline
        Write-Host $ID -ForegroundColor Magenta
        Write-Host "Message: " -NoNewline
        Write-Host $Message -ForegroundColor Red
        Write-Host "......................................................."
     
        Log-ScriptEvent $LogFilePath "Event Time: $Time EVent ID: $ID" NDES_Validation 3
        Log-ScriptEvent $LogFilePath "Message: $Message" NDES_Validation 3
    }
} else {

    Write-Host "Success: " -ForegroundColor Green -NoNewline
    write-Host "No errors found in the Microsoft Intune Connector " -NoNewline
    Write-Host "Admin Event log" -ForegroundColor Cyan
    Write-Host "......................................................."
    Log-ScriptEvent $LogFilePath "No errors found in the Microsoft Intune Connector Admin Event log" NDES_Validation 3

}

# Get the error & Warning events from the intune connector log and check error. Get last 5
$errorEventsOperationalLog = Get-WinEvent -FilterHashtable @{LogName=$ConnectorlogOperational;StartTime=$EventstartTime} | Where-Object -FilterScript {($_.Level -eq 2) -or ($_.Level -eq 3)} | Select-Object -First 5 -ErrorAction SilentlyContinue 

# Display the error events in opertional log
if ($errorEventsOperationalLog) {
    
    write-host "Errors found in the Microsoft Intune Connector Opertional Event log" -BackgroundColor Red
    write-host "List first 5 errors in the Microsoft Intune Connector Opertional Event log" -BackgroundColor Red

    Log-ScriptEvent $LogFilePath "Errors found in the Microsoft Intune Connector Opertional Event log" NDES_Validation 3
    Log-ScriptEvent $LogFilePath "List first 5 errors in the Microsoft Intune Connector Opertional Event log" NDES_Validation 3
    
    foreach ($event in $errorEventsOperationalLog) {
        
        $Time = $event.TimeCreated
        $ID = $event.Id
        $Message = $event.Message
    
        Write-Host "......................................................."
        Write-Host "Event Time: "-NoNewline
        Write-Host $Time -ForegroundColor Cyan
        Write-Host "EVent ID: " -NoNewline
        Write-Host $ID -ForegroundColor Magenta
        Write-Host "Message: " -NoNewline
        Write-Host $Message -ForegroundColor Red
        Write-Host "......................................................."
        Write-Host ""
        Log-ScriptEvent $LogFilePath "Event Time: $Time EVent ID: $ID" NDES_Validation 3
        Log-ScriptEvent $LogFilePath "Message: $Message" NDES_Validation 3
    }
} else {
    
    Write-Host "Success: " -ForegroundColor Green -NoNewline
    write-host "No errors found in the Microsoft Intune Connector " -NoNewline
    Write-Host "Opertional Event log" -ForegroundColor Cyan 
    Write-Host "......................................................."
    Log-ScriptEvent $LogFilePath "No errors found in the Microsoft Intune Connector Opertional Event log" NDES_Validation 3

}
  
  
  #Checking error event in Application log and source from NetworkDeviceEnrollmentService
  $errorEventsApplicationLog = Get-EventLog -LogName "Application" -EntryType Error -Source PKICertificateConnectorSvc,PFXCertificateConnectorSvc,Microsoft-Windows-NetworkDeviceEnrollmentService -After $EventstartTime -Newest 5 | Select-Object TimeGenerated,Source,Message

 if (-not ($errorEventsApplicationLog)) {

        Write-Host "Success: " -ForegroundColor Green -NoNewline
        write-host "No errors found in the Application log from source NetworkDeviceEnrollmentService or NDESConnector"
        Write-host
        Log-ScriptEvent $LogFilePath "No errors found in the Application log from source NetworkDeviceEnrollmentService or NDESConnector"  NDES_Validation 1

    }else {

            Write-Warning "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-Host
            $errorEventsApplicationLog | Format-List
    

            foreach ($item in $errorEventsApplicationLog) {

                Log-ScriptEvent $LogFilePath "$($item.TimeGenerated);$($item.Message);$($item.Source)"  NDES_Eventvwr 3
            }
        }


Log-ScriptEvent $LogFilePath "*********************************************************************************"  NDES_Validation 3
$ErrorActionPreference = "Continue"

#endregion

################################################################
y
#Region Check Azure proxy event log for connector update



#endregion

#################################################################

#Region Check IIS log



#endregion

#################################################################

#region Zip up logfiles
Write-host "......................................................."
Write-host
Write-host "Log Files.............................................." -ForegroundColor Yellow
Write-host 
write-host "Do you want to gather troubleshooting files? This includes IIS, NDES Connector logs in addition to the SCEP template configuration. [Y]es, [N]o:"
$LogFileCollectionConfirmation = Read-Host

if($LogFileCollectionConfirmation -eq "y"){

    #get IIS log file location
    $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

    # Get the Event Log path
    $ConnectorAdminEventLogFile = Get-WinEvent -ListLog "Microsoft-Intune-CertificateConnectors/Admin" | Select-Object -ExpandProperty LogFilePath
    $ConnectorAdminEventLogFilePath = [System.Environment]::ExpandEnvironmentVariables($ConnectorAdminEventLogFile)

    $ConnectorOperationalEventLogFile = Get-WinEvent -ListLog "Microsoft-Intune-CertificateConnectors/Operational" | Select-Object -ExpandProperty LogFilePath
    $ConnectorOperationalEventLogFilePath = [System.Environment]::ExpandEnvironmentVariables($ConnectorOperationalEventLogFile)
    
    #Copy IIS log to log file location
    foreach ($IISLog in $IISLogs){
        
        Copy-Item -Path $IISLog.FullName -Destination $TempDirPath
    
    }
    
    Copy-Item -Path $ConnectorAdminEventLogFilePath -Destination $TempDirPath
    Copy-Item -Path $ConnectorOperationalEventLogFilePath -Destination $TempDirPath

    #This following use to check cert template
#$SCEPUserCertTemplateOutputFilePath = "$($TempDirPath)\SCEPUserCertTemplate.txt"
# certutil -v -template $SCEPUserCertTemplate > $SCEPUserCertTemplateOutputFilePath

Log-ScriptEvent $LogFilePath "This is the end of 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-host
Write-Host "Success: " -ForegroundColor Green -NoNewline
write-host "Log files copied to $env:temp\$($date)-Logs-$($hostname).zip"
Write-host

}else {
    
    Log-ScriptEvent $LogFilePath "Do not collect logs"  NDES_Validation 1
    #$WriteLogOutputPath = $True
}


#endregion

#################################################################


} else {

        Write-Host
        Write-host "......................................................."
        Write-Host
        Write-host "Incorrect variables. Please run the script again..." -ForegroundColor Red
        Write-Host
        Write-Host "Exiting................................................"
        Write-Host
        exit

}