data _system_translations {
ConvertFrom-StringData @'
# fallback text goes here (optional)
NpsServiceStatus_Title=The Network Policy Server (NPS) service should be running.
NpsServiceStatus_Problem=The Network Policy Server (NPS) service is not running.
NpsServiceStatus_Impact=The Network Policy Server (NPS) service is unavailable. Client computers requesting access to the network cannot authenticate and are denied network access.
NpsServiceStatus_Resolution=Start the Network Policy Server (NPS) service.
NpsServiceStatus_Compliant=The NPAS Best Practices Analyzer scan has determined that you are in compliance with this best practice.
AtleastOneCAConfigured_Title=The Health Registration Authority (HRA) server should be configured with at least one valid certification authority (CA).
AtleastOneCAConfigured_Problem=The Health Registration Authority (HRA) server is not configured with a valid certification authority (CA).
AtleastOneCAConfigured_Impact=The Health Registration Authority (HRA) server cannot acquire health certificates on behalf of Network Access Protection (NAP) clients. NAP client computers are denied network access.
AtleastOneCAConfigured_Resolution=Configure the Health Registration Authority (HRA) server with at least one valid certification authority (CA).
AtleastOneCAConfigured_Compliant=The NPAS Best Practices Analyzer scan has determined that you are in compliance with this best practice.
HraAcceptsHttpHttps_Title=Internet Information Services (IIS) settings for the Health Registration Authority (HRA) server should accept HTTP and HTTPS communication.
HraAcceptsHttpHttps_Problem_Warning=Internet Information Services (IIS) settings for the Health Registration Authority (HRA) server do not accept HTTP and HTTPS communication.
HraAcceptsHttpHttps_Problem_Error=Internet Information Services (IIS) settings for the Health Registration Authority (HRA) server do not accept HTTP or HTTPS communication.
HraAcceptsHttpHttps_Impact_Warning=Network Access Protection (NAP) client computers might not be able to acquire health certificates or communications with NAP client computers will not be encrypted with Secure Sockets Layer (SSL).
HraAcceptsHttpHttps_Impact_Error=Network Access Protection (NAP) client computers cannot obtain health certificates.
HraAcceptsHttpHttps_Resolution=To enable HTTPS communication, provision a Secure Sockets Layer (SSL) certificate on the Health Registration Authority (HRA) server, and then configure Internet Information Services (IIS) to accept HTTPS requests. To enable HTTP communication, configure IIS to accept HTTP requests.
HraAcceptsHttpHttps_Compliant=The NPAS Best Practices Analyzer scan has determined that you are in compliance with this best practice.
FirewallExemptionForHttpHttps_Title=Firewall settings for the Health Registration Authority (HRA) server should allow HTTP and HTTPS communication.
FirewallExemptionForHttpHttps_Problem_Error=Firewall settings for the Health Registration Authority (HRA) server do not allow HTTP and HTTPS communications.
FirewallExemptionForHttpHttps_Problem_Warning=Firewall settings for the Health Registration Authority (HRA) do not allow HTTP or HTTPS communication.
FirewallExemptionForHttpHttps_Impact_Error=Incoming health certificate requests are blocked. Network Access Protection (NAP) client computers cannot obtain a health certificate from the Health Registration Authority (HRA) server.
FirewallExemptionForHttpHttps_Impact_Warning=Incoming health certificate requests might be blocked. If certificate requests are blocked, Network Access Protection (NAP) client computers cannot obtain a health certificate from the Health Registration Authority (HRA) server.
FirewallExemptionForHttpHttps_Resolution=Configure firewall exemption settings to allow HTTP and HTTPS communication for the Health Registration Authority (HRA) server.
FirewallExemptionForHttpHttps_Compliant=The NPAS Best Practices Analyzer scan has determined that you are in compliance with this best practice.
IISComponentsInstalled_Title=The Health Registration Authority (HRA) server should have all required Internet Information Services (IIS) components installed.
IISComponentsInstalled_Problem=Required Internet Information Services (IIS) components are not installed on the Health Registration Authority (HRA) server.
IISComponentsInstalled_Impact=The Health Registration Authority (HRA) server cannot process health certificate requests. Network Access Protection (NAP) client computers are denied network access.
IISComponentsInstalled_Resolution=Reinstall the Health Registration Authority (HRA) role service and all dependent roles and role features.
IISComponentsInstalled_Compliant=The NPAS Best Practices Analyzer scan has determined that you are in compliance with this best practice.
NpsCrpEnabled_Title=Network Policy Server (NPS) should have at least one connection request policy enabled.
NpsCrpEnabled_Problem=No connection request policies are enabled on Network Policy Server (NPS).
NpsCrpEnabled_Impact=Client computers requesting access to the network cannot authenticate and are denied network access.
NpsCrpEnabled_Resolution=Create and enable a connection request policy on Network Policy Server (NPS) to process client computer authentication requests.
NpsCrpEnabled_Compliant=The NPAS Best Practices Analyzer scan has determined that you are in compliance with this best practice.
NpsNetworkPolicyEnabled_Title=Network Policy Server (NPS) should have at least one network policy enabled.
NpsNetworkPolicyEnabled_Problem=No network policies are enabled on Network Policy Server (NPS).
NpsNetworkPolicyEnabled_Impact=Client computers requesting access to the network cannot be authorized and are denied network access.
NpsNetworkPolicyEnabled_Resolution=Create and enable a network policy on Network Policy Server (NPS) to process client computer authorization requests.
NpsNetworkPolicyEnabled_Compliant=The NPAS Best Practices Analyzer scan has determined that you are in compliance with this best practice.
CertificateLifeTime_Title=The Health Registration Authority (HRA) server should be configured with a validity time for health certificates of at least 20 minutes and no more than 24 hours.
CertificateLifeTime_Problem=The validity time configured for health certificates is less than 20 minutes or more than 24 hours.
CertificateLifeTime_Impact=Network Access Protection (NAP) client computers will renew their health certificates too frequently or infrequently, and might be unable to acquire a health certificate.
CertificateLifeTime_Resolution=Configure the validity time for health certificates to be greater than 20 minutes, but less than 24 hours.
CertificateLifeTime_Compliant=The NPAS Best Practices Analyzer scan has determined that you are in compliance with this best practice.
NpsAuthentication_Title=Network Policy Server (NPS) should be configured to use more secure authentication methods.
NpsAuthentication_Problem=Network Policy Server (NPS) has the following policies configured that use less secure authentication methods.{0}{1}
NpsAuthentication_Impact=Client computers requesting network access can use authentication methods that are less secure.
NpsAuthentication_Resolution=Configure Network Policy Server (NPS) to use more secure authentication methods such as PEAP-MSCHAPv2 or PEAP-TLS. Identical authentication methods must also be configured on client computers.
NpsAuthentication_Compliant=The NAP Best Practices Analyzer scan has determined that you are in compliance with this best practice.
NasRunningLocally_Title=Network Policy Server (NPS) should be configured as a network access server (NAS), or NPS should be configured with RADIUS clients.
NasRunningLocally_Problem=Network Policy Server (NPS) is not configured as a network access server (NAS) and RADIUS clients are not configured and enabled.
NasRunningLocally_Impact=Network access requests cannot be evaluated by Network Policy Server (NPS). Client computers requesting access to the network cannot authenticate and are denied network access.
NasRunningLocally_Resolution=Configure and enable RADIUS clients, or configure Network Policy Server (NPS) as a network access server (NAS).
NasRunningLocally_Compliant=The NPAS Best Practices Analyzer scan has determined that you are in compliance with this best practice.
PolicyType_CRP=Connection request policies:
PolicyType_NP=Network policies:
'@
}
Import-LocalizedData -BindingVariable _system_translations -filename NPAS.psd1
# Function Description:
# Append some general info (not specific to any role service)
#
# Arguments:
# parent xml node, under which to add the general info nodes
#
# Return Value:
# None
#
function GeneralInfo($element)
{
$now = Get-Date ;
$nodeNow = $element.ownerDocument.CreateElement("ScanTime", $tns);
$nodeTxt = $nodeNow.ownerDocument.CreateTextNode( $now.ToString("o") );
[void]$nodeNow.AppendChild( $nodeTxt );
$nodeNow.setAttribute("ticks", $now.Ticks);
[void]$element.AppendChild($nodeNow);
}
# helper function to create document
function Create-DocumentElement($ns, $name )
{
[xml] "<$name xmlns='$ns'/>"
}
$tns="http://schemas.microsoft.com/mbca/models/NPAS/2009/11"
# create a new XmlDocument
$doc = Create-DocumentElement $tns "NPAS"
#
# Create a new XmlDocument
#
GeneralInfo $doc.DocumentElement ;
$NPSNode = $doc.CreateElement("NPSSERVER",$tns)
[void]$doc.DocumentElement.AppendChild($NPSNode)
$HRANode = $doc.CreateElement("HRASERVER",$tns)
[void]$doc.DocumentElement.AppendChild($HRANode)
#$NodeNPASComposite = setXmlElement $doc $doc.DocumentElement $tns "NPASComposite"
#
# Function Description:
#
# This function will add the Server Manager module so that Roles
# can be queried
#
# Arguments:
#
# None
#
# Return Value:
#
# None
#
function RoleQueryInitialize
{
Import-Module ServerManager
}
#
# Function Description:
#
# This function will remove the Server Manager module after the Roles
# have been queried
#
# Arguments:
#
# None
#
# Return Value:
#
# None
#
function RoleQueryShutdown
{
Remove-Module ServerManager
}
#
# Function Description:
#
# This function will check to see if the specified role is installed
#
# Arguments:
#
# $roleId - Id of the Role
#
# Return Value:
#
# $true - If Role is Installed
# $false - If Role is not Installed
#
function IsRoleInstalled ( $roleId )
{
$roleInstalled = $false
# Use the Server Manager CmdLet to obtain detail about Role
$Role = Get-WindowsFeature $roleId
if ( $Role -ne $null )
{
$roleInstalled = $Role.Installed
}
# Return the result
return $roleInstalled
}
# Function Description:
# Checks if the specified Service is Running
#
# Arguments:
# $serviceName: Service Name
#
# Return Value:
# Boolean. true if the service is running, false otherwise
function IsServiceRunning($serviceName)
{
if (-not ([appdomain]::CurrentDomain.getassemblies() |? {$_.ManifestModule -like “system.serviceprocess”})) {[void][System.Reflection.Assembly]::LoadWithPartialName(’system.serviceprocess’)}
$result = $false
$machineName = "localhost"
$serviceResults = [System.ServiceProcess.ServiceController]::GetServices($machineName) | where{ (($_.name -eq $serviceName) -or ($_.displayname -eq $serviceName))}
if ($serviceResults -eq $null)
{
$result = $false
}
else
{
$serviceStatus = get-service $serviceResults.name
$result = $serviceStatus.status -eq "Running"
}
# Return the result of the rule
return $result
}
#
# Function Description:
#
# This function will create and return a COM Object
#
# Arguments:
#
# $ProgId - Specifies type of COM object to create
#
# Return Value:
#
# $comObj - Newly created COM object
# $null - if failure
#
function CreateComObject ( $ProgId )
{
$comObj = New-Object -com $ProgId
return $comObj
}
# Function Description:
# This function will obtain the Config String for the CA identified by $flags
#
# Arguments:
# $flags - Flags which identify the CA
#
# Return Value:
# $configString - Config String for the specified CA
# $null - if failure
#
function GetCAConfigString ( $flags )
{
$certConfig = CreateComObject "CertificateAuthority.Config.1"
if ($certConfig -eq $null)
{
return $null
}
$configString = $certConfig.GetConfig( $flags )
return $configString
}
# Function Description:
# This function will obtain Type of specified CA
#
# Arguments:
# $certAdmin - CertificateAuthority Admin object
# $configString - Config String which identifies the CA
#
# Return Value:
# $caType - Type of the specified CA
# $null - if failure
#
function GetCAType ( $certAdmin, $configString )
{
if ( !$certAdmin -or !$configString )
{
return $null
}
$caType = $certAdmin.GetCAProperty( $configString, 10, 0, 1, 2 )
# Return the result
return $caType
}
# Function Description:
# This function will check if CA is Enterprise CA
#
# Arguments:
# $caTypeEnum - Type of CA to check against
# $caType - Type of CA
#
# Return Value:
# $true - if CA is of specified type
# $false - otherwise
#
function CheckCAType( $caTypeEnum, $caType )
{
$compare = $false
switch ( $catypeEnum )
{
"Enterprise"
{
# Compare with ENTERPRISE_ROOTCA(0) or ENUM_ENTERPRISE_SUBCA(1)
if ( ( $caType -eq 0 ) -or ( $caType -eq 1 ) )
{
$compare = $true
}
}
"StandAlone"
{
# Compare with ENUM_STANDALONE_ROOTCA(3)
if ( $caType -eq 3 )
{
$compare = $true
}
}
}
# Return the result
return $compare
}
# Function Description:
# Checks if
# 1. the CA is installed
# 2. CA is running
# 3. CA is StandAlone CA
#
# Arguments:
# $ADCSCertAuthorityInstalled - boolean value which indicates if CA is installed
#
# Return Value:
# $IsStandAloneCA- true if StandAlone CA is installed and running, false otherwise
#
function IsStandAloneCARunning($ADCSCertAuthorityInstalled)
{
$result = $false
if ($ADCSCertAuthorityInstalled -eq $true)
{
# Pre-Check whether the service is running
$ADCSRunning = IsServiceRunning "certsvc"
if ($ADCSRunning -eq $true)
{
# Create the Certificate Admin Object
$certAdmin = CreateComObject "CertificateAuthority.Admin.1"
# Obtain the config string for the CA using CC_LOCALCONFIG (0x3)
$certConfigFlags = 0x3
$configString = GetCAConfigString $certConfigFlags
# Obtain the type of CA
$caType = GetCAType $certAdmin $configString
# Check to see if this is a StandAlone CA
$result = CheckCAType "StandAlone" $caType
}
}
# Return the result
return $result
}
# Function Description:
# Checks if NPS service is Running
#
# Arguments:
# None
#
# Return Value:
# Boolean. true if NPS service is running, false otherwise
function IsNpsServiceStatus
{
$result = $false
$result = IsServiceRunning "ias"
# Return the result of the rule
return $result
}
# Function Description:
# Checks if atleast one Connection Request Policy is enabled
#
# Arguments:
# $xdNpsSvrCfg: NPS configuration
#
# Return Value:
# Boolean. true if atleast one Connection Request Policy is enabled,
# false otherwise
#
function IsNpsCrpEnabled($xdNpsSvrCfg)
{
$result = $false
$temp = $xdNpsSvrCfg.Root.Children.Microsoft_Internet_Authentication_Service
$proxyPoliciesNode = $temp.Children.Proxy_Policies.Children
# If CRP node exists
if($proxyPoliciesNode)
{
# For each CRP, find if any is enabled
$proxyPoliciesEnumerator = $proxyPoliciesNode.GetEnumerator()
foreach($_ in $proxyPoliciesEnumerator)
{
if($_.Properties.Policy_Enabled)
{
$proxyEnabled = $_.Properties.Policy_Enabled.'#text'
}
else
{
# If Proxy_Enabled Tag does not exist then the default policy is enabled.
$proxyEnabled = '1'
}
if($proxyEnabled -eq '1')
{
$result = $true
break
}
}
} #endof if($proxyPoliciesNode)
# Return the result of the rule
return $result
}
# Function Description:
# Checks if Radius Server Group exists corresponding to the Proxy profile
#
# Arguments:
# $xdNpsSvrCfg: NPS configuration
# $proxyProfilesName: Name of the Proxy Profile
#
# Return Value:
# Boolean. true if Radius Server Group exists for the corresponding
# Proxy Profile, false otherwise
#
function DoesRadiusServerGroupExists($xdNpsSvrCfg, $proxyProfilesName)
{
$temp = $xdNpsSvrCfg.Root.Children.Microsoft_Internet_Authentication_Service
$radiusServerGroupsNode = $temp.Children.RADIUS_Server_Groups.Children
if($radiusServerGroupsNode)
{
$radiusServerGroupsEnumerator = $radiusServerGroupsNode.GetEnumerator()
foreach($_ in $radiusServerGroupsEnumerator)
{
# ensure that the name configured in proxy profile exists in
# Radius Server Group
if($_.name -eq $proxyProfilesName)
{
# We have identified that the server acts as a proxy
$result = $true
break
}
}
}
$result
}
# Function Description:
# Checks if NPS proxy is enabled for the given Proxy Policy
#
# Arguments:
# $xdNpsSvrCfg: NPS configuration
# $proxyPoliciesName: Name of the Proxy Policy
#
# Return Value:
# Boolean. true if Nps is configured as a Proxy for the given Proxy profile,
# false otherwise
#
function DoesProxyProfileExists($xdNpsSvrCfg, $proxyPoliciesName)
{
$temp = $xdNpsSvrCfg.Root.Children.Microsoft_Internet_Authentication_Service
$proxyProfilesNode = $temp.Children.Proxy_Profiles.Children
# obtain the corresponding msAuthProviderName
if($proxyProfilesNode)
{
$proxyProfilesEnumerator = $proxyProfilesNode.GetEnumerator()
foreach($_ in $proxyProfilesEnumerator)
{
if($_.name -eq $proxyPoliciesName)
{
$proxyProfilesName = $_.Properties.msAuthProviderName.'#text'
$result = DoesRadiusServerGroupExists $xdNpsSvrCfg $proxyProfilesName
}
if($result -eq $true)
{
# We have identified that the server acts as a proxy
break
}
} # endof foreach($_ in $proxyProfilesEnumerator)
}
$result
}
# Function Description:
# Checks if Nps Server is configured as a Proxy
#
# Arguments:
# $xdNpsSvrCfg: NPS configuration
#
# Return Value:
# Boolean. true if Nps Server is configured as a Proxy,
# false otherwise
#
function IsNpsProxyConfigured($xdNpsSvrCfg)
{
# For NPS to be configured as a proxy, we need to check Proxy_Policies node
# For each enabled Proxy_Policies, we need to identify the Profile which has a
# valid Radius Server configured
$result = $false
$temp = $xdNpsSvrCfg.Root.Children.Microsoft_Internet_Authentication_Service
$proxyPoliciesNode = $temp.Children.Proxy_Policies.Children
if($proxyPoliciesNode)
{
$proxyPoliciesEnumerator = $proxyPoliciesNode.GetEnumerator()
foreach($_ in $proxyPoliciesEnumerator)
{
# check if proxy policy is enabled
$proxyPoliciesName = $_.name
$proxyEnabled = $_.Properties.Policy_Enabled.'#text'
# Only for the proxy policy which are enabled, iterate through all
# the profiles
if($proxyEnabled -eq '1')
{
$result = DoesProxyProfileExists $xdNpsSvrCfg $proxyPoliciesName
}
if($result -eq $true)
{
# We have identified that the server acts as a proxy
break
}
} #endof foreach($_ in $proxyPoliciesEnumerator)
} #endof if($proxyPoliciesNode)
# Return the result
return $result
}
# Function Description:
# Checks if atleast one Network Policy is enabled
#
# Arguments:
# $xdNpsSvrCfg: NPS configuration
#
# Return Value:
# Boolean. true if atleast one Network Policy is enabled,
# false otherwise
#
function IsNpsNetworkPolicyEnabled($xdNpsSvrCfg)
{
#If NPS is configured as a proxy, then we need not have Network Policy enabled
$result = $false
#Find if NPS is configured as a proxy
$boolNpsProxyConfigured = IsNpsProxyConfigured($xdNpsSvrCfg)
$networkPolicyEnabledCount = 0
$temp = $xdNpsSvrCfg.Root.Children.Microsoft_Internet_Authentication_Service
$networkPolicyNode = $temp.Children.NetworkPolicy.Children
# If Network Policy Node exists
if($networkPolicyNode)
{
# For each Network Policy, find if any is enabled
$networkPolicyEnumerator = $networkPolicyNode.GetEnumerator()
foreach($_ in $networkPolicyEnumerator)
{
if($_.Properties.Policy_Enabled)
{
$networkPolicyEnabled = $_.Properties.Policy_Enabled.'#text'
}
else
{
# If Policy_Enabled Tag does not exist then the default policy is enabled.
$networkPolicyEnabled = '1'
}
if($networkPolicyEnabled -eq '1')
{
$networkPolicyEnabledCount += 1
}
}
} #endof if($NetworkPolicyNode)
# Atleast one Network Policy should be enabled or NPS should be a proxy
$result = (($networkPolicyEnabledCount -ge 1) -or
($boolNpsProxyConfigured -eq $true))
# Return the result of the rule
return $result
}
# Function Description:
# Verifies authentication method
#
# Arguments:
# $ProfileNode: Either CRP or NP node
#
# Return Value:
# result - Array of CRPs/NPs names which are configured with less secure
# authentication methods
# count - This is pass by reference and indicates the number of CRPs/NPs
# that are configured with less secure authentication methods.
# caller doesn't have to initialize the value of count
function CheckAuthenticationMethod($profileNode, [REF]$count)
{
# Authentication Methods Attribute in ias.xml and its value
# Pap, Spap msNPAuthenticationType2 = 1
# Chap msNPAuthenticationType2 = 2
# msChap msNPAuthenticationType2 = 3
# msChapv2 msNPAuthenticationType2 = 4
# WithoutAuth msNPAuthenticationType2 = 7
# Peap msNPAuthenticationType2 = 5,
# msNPAllowedEapType = "19" followed by 30 zero
# EAP-MSChap v2 msNPAuthenticationType2 = 5,
# msNPAllowedEapType = "1a" followed by 30 zero
$AuthType = @{}
$AuthType.PAP = 1
$AuthType.CHAP = 2
$AuthType.MSCHAP = 3
$AuthType.MSCHAPV2 = 4
$AuthType.EAP = 5
$AuthType.WithoutAuth = 7
$isSupportedEapType = $TRUE;
$isSavedMachineHealthCheckOnly = $FALSE;
$result = @()
$count.Value = 0
# check if node exists
if($profileNode)
{
# Enumerate each profile
$profileEnumerator = $profileNode.GetEnumerator()
foreach($_ in $profileEnumerator)
{
# for every Radius Profile, initialize the values
$isSupportedEapType = $TRUE;
$isSavedMachineHealthCheckOnly = $FALSE;
# Ensure supported EAP methods are configured
$msNPAllowedEapTypeNode = $_.Properties.msNPAllowedEapType
foreach($msNPAllowedEapType in $msNPAllowedEapTypeNode)
{
if($msNPAllowedEapType.'#text' -eq '04000000000000000000000000000000' -or
$msNPAllowedEapType.'#text' -eq '1a000000000000000000000000000000'
)
{
$isSupportedEapType = $FALSE;
}
}
# Ensure "Perform machine health check only" is not enabled
$msSavedMachineNode = $_.Properties.msSavedMachineHealthCheckOnly
foreach($msSavedMachineType in $msSavedMachineNode)
{
if($msSavedMachineType.'#text' -eq '1')
{
$isSavedMachineHealthCheckOnly = $TRUE;
}
}
# Ensure supported Authentication methods are configured
$msNPAuthenticationTypeNode = $_.Properties.msNPAuthenticationType2
foreach($msNPAuthenticationType in $msNPAuthenticationTypeNode)
{
if($msNPAuthenticationType.'#text' -eq $AuthType.PAP -or
$msNPAuthenticationType.'#text' -eq $AuthType.CHAP -or
$msNPAuthenticationType.'#text' -eq $AuthType.MSCHAP -or
$msNPAuthenticationType.'#text' -eq $AuthType.MSCHAPV2 -or
($msNPAuthenticationType.'#text' -eq $AuthType.WithoutAuth -and
$isSavedMachineHealthCheckOnly -eq $FALSE) -or
($msNPAuthenticationType.'#text' -eq $AuthType.EAP -and
$isSupportedEapType -eq $FALSE)
)
{
$temp = " " + $_.name
$result = $result + $temp
$count.Value += 1
break
}
}
} # endof foreach($_ in $radiusProfileEnumerator)
} # endof if($radiusProfileNode)
# Return the result of the rule
return $result
}
# Function Description:
# Verifies Supported authentication method are configured for CRP and NP
#
# Arguments:
# $xdNpsSvrCfg: NPS configuration
#
# Return Value:
# returns an xml blob
#
#
function CheckNpsAuthenticationMethod($xdNpsSvrCfg)
{
$isSupportedAuthForNP = $false
$isSupportedAuthForCRP = $false
# We need to check CRP and NP for Authentication methods
$temp = $xdNpsSvrCfg.Root.Children.Microsoft_Internet_Authentication_Service
$radiusProfileNode = $temp.Children.RadiusProfiles.Children
$proxyProfileNode = $temp.Children.Proxy_Profiles.Children
$authResult = @{}
$npCount = 0
$crpCount = 0
$authResult.np = CheckAuthenticationMethod $radiusProfileNode ([REF]$npCount)
$authResult.crp = CheckAuthenticationMethod $proxyProfileNode ([REF]$crpCount)
if($crpCount -gt 0)
{
$crpList = $authResult.crp -join "`n"
$crpList = $crpList -replace '{',' '
$crpList = $crpList -replace '}',' '
$crpList = "`n`n " + $_system_translations.PolicyType_CRP + "`n" + $crpList
}
if($npCount -gt 0)
{
$npList = $authResult.np -join "`n"
$npList = $npList -replace '{',' '
$npList = $npList -replace '}',' '
$npList = "`n`n " + $_system_translations.PolicyType_NP + "`n" + $npList
}
if (! ($npCount -eq 0 -and $crpCount -eq 0))
{
$result =
@"
false
$crpList
$npList
"@
}
else
{
$result =
@"
true
"@
}
# Return the result of the rule
return $result
}
# Function Description:
# Verifies if there is any NAS services running locally
#
# Arguments:
# $xdNpsSvrCfg: NPS configuration
#
# Return Value:
# Boolean. true if atleast one NAS is running locally,
# false otherwise
#
function IsNasRunningLocally($xdNpsSvrCfg)
{
$result = $false
$radiusClientEnabled = '0'
#check if any Radius client is configured
$temp1 = $xdNpsSvrCfg.Root.Children.Microsoft_Internet_Authentication_Service
$temp2 = $temp1.Children.Protocols.Children.Microsoft_Radius_Protocol
$radiusClientsNode = $temp2.Children.Clients.Children
if($radiusClientsNode)
{
$radiusClientsEnumerator = $radiusClientsNode.GetEnumerator()
foreach($_ in $radiusClientsEnumerator)
{
$radiusClientEnabled = $_.Properties.Radius_Client_Enabled.'#text'
}
}
# Initialize to perform querying Role information
RoleQueryInitialize
# RRAS installed
$rrasInstalled = (IsRoleInstalled “NPAS”) -and
(IsRoleInstalled “NPAS-RRAS-Services”) -and
(IsRoleInstalled “NPAS-RRAS”)
# DHCP installed
$dhcpInstalled = IsRoleInstalled “DHCP”
# TSG installed
$tsgInstalled = IsRoleInstalled "RDS-Gateway"
# HRA installed
$hraInstalled = (IsRoleInstalled “NPAS”) -and
(IsRoleInstalled “NPAS-Health”)
# HCAP installed
$hcapInstalled = (IsRoleInstalled “NPAS”) -and
(IsRoleInstalled “NPAS-Host-Cred”)
# Role Information obtained.
RoleQueryShutdown
# RRAS service Running
$rrasRunning = $false
$rrasRunning = IsServiceRunning "RemoteAccess"
# DHCP service Running
$dhcpRunning = $false
$dhcpRunning = IsServiceRunning "DHCPServer"
# TSG service Running
$tsgRunning = $false
$tsgRunning = IsServiceRunning "TSGateway"
$allNasSourceTagCRP = $false
$tsgSourceTagCRP = $false
$rrasSourceTagCRP = $false
$dhcpSourceTagCRP = $false
$hraSourceTagCRP = $false
$hcapSourceTagCRP = $false
$allNasSourceTagNP = $false
$tsgSourceTagNP = $false
$rrasSourceTagNP = $false
$dhcpSourceTagNP = $false
$hraSourceTagNP = $false
$hcapSourceTagNP = $false
# Get Policy_SourceTag of CRP
$temp = $xdNpsSvrCfg.Root.Children.Microsoft_Internet_Authentication_Service
$proxyPolicyNode = $temp.Children.Proxy_Policies.Children
# Get Policy_SourceTag of NP
$networkPolicyNode = $temp.Children.NetworkPolicy.Children
# If Proxy Policy Node exists
if($proxyPolicyNode)
{
# For each CRP, find the sourceTag
$proxyPolicyEnumerator = $proxyPolicyNode.GetEnumerator()
foreach($_ in $proxyPolicyEnumerator)
{
$proxyPolicyEnabled = $_.Properties.Policy_Enabled.'#text'
if($proxyPolicyEnabled -eq '1')
{
switch($_.Properties.Policy_SourceTag.'#text')
{
"0" { $allNasSourceTagCRP = $true }
"1" { $tsgSourceTagCRP = $true }
"2" { $rrasSourceTagCRP = $true }
"3" { $dhcpSourceTagCRP = $true }
"5" { $hraSourceTagCRP = $true }
"6" { $hcapSourceTagCRP = $true }
}
}
}
} #endof if($ProxyPolicyNode)
# If Network Policy Node exists
if($networkPolicyNode)
{
# For each Network Policy, find the sourceTag
$networkPolicyEnumerator = $networkPolicyNode.GetEnumerator()
foreach($_ in $networkPolicyEnumerator)
{
$networkPolicyEnabled = $_.Properties.Policy_Enabled.'#text'
if($networkPolicyEnabled -eq '1')
{
switch($_.Properties.Policy_SourceTag.'#text')
{
"0" { $allNasSourceTagNP = $true }
"1" { $tsgSourceTagNP = $true }
"2" { $rrasSourceTagNP = $true }
"3" { $dhcpSourceTagNP = $true }
"5" { $hraSourceTagNP = $true }
"6" { $hcapSourceTagNP = $true }
}
}
}
} #endof if($networkPolicyNode)
# Check if IIS is installed
$iisInstalled = IsIISComponentsInstalled
# Check if IIS is running
$iisRunning = $false
$iisRunning = IsServiceRunning "w3svc"
# Is NPS configured as a proxy
$boolNpsProxyConfigured = IsNpsProxyConfigured($xdNpsSvrCfg)
if($boolNpsProxyConfigured -eq $true)
{
# If NPS is configred as a proxy, then check whether NAS is enabled in CRP
$rrasConfigured = $rrasInstalled -and
$rrasRunning -and
($allNasSourceTagCRP -or $rrasSourceTagCRP)
$hraConfigured = $hraInstalled -and
$iisInstalled -and
$iisRunning -and
($allNasSourceTagCRP -or $hraSourceTagCRP)
$hcapConfigured = $hcapInstalled -and
$iisInstalled -and
$iisRunning -and
($allNasSourceTagCRP -or $hcapSourceTagCRP)
$dhcpConfigured = $dhcpInstalled -and
$dhcpRunning -and
($allNasSourceTagCRP -or $dhcpSourceTagCRP)
$tsgConfigured = $tsgInstalled -and
$tsgRunning -and
($allNasSourceTagCRP -or $tsgSourceTagCRP)
}
else
{
# If NPS is NOT configred as a proxy, then check whether NAS is enabled
# in CRP and NP
$rrasConfigured = $rrasInstalled -and
$rrasRunning -and
($allNasSourceTagCRP -or $rrasSourceTagCRP) -and
($allNasSourceTagNP -or $rrasSourceTagNP)
$hraConfigured = $hraInstalled -and
$iisInstalled -and
$iisRunning -and
($allNasSourceTagCRP -or $hraSourceTagCRP) -and
($allNasSourceTagNP -or $hraSourceTagNP)
$hcapConfigured = $hcapInstalled -and
$iisInstalled -and
$iisRunning -and
($allNasSourceTagCRP -or $hcapSourceTagCRP) -and
($allNasSourceTagNP -or $hcapSourceTagNP)
$dhcpConfigured = $dhcpInstalled -and
$dhcpRunning -and
($allNasSourceTagCRP -or $dhcpSourceTagCRP) -and
($allNasSourceTagNP -or $dhcpSourceTagNP)
$tsgConfigured = $tsgInstalled -and
$tsgRunning -and
($allNasSourceTagCRP -or $tsgSourceTagCRP) -and
($allNasSourceTagNP -or $tsgSourceTagNP)
}
$result = ($radiusClientEnabled -eq '1' -or
$rrasConfigured -or
$hraConfigured -or
$hcapConfigured -or
$dhcpConfigured -or
$tsgConfigured)
# Return the result of the rule
return $result
}
# Function Description:
# Checks if HRA is configured to point to atleast one valid Certificate Authority
#
# Arguments:
# None
#
# Return Value:
# Boolean. true if atleast one CA is configured, false otherwise
function IsAtleastOneCAReachable
{
$CAReachable = $false
$availableCAString = ""
$configuredCAString = ""
# Get a list of valid CAs
$certConfig = CreateComObject "CertificateAuthority.Config.1"
if ($certConfig -eq $null)
{
Write-Host "Error"
}
$FieldName = "Config"
$caCount = $certConfig.Reset(0)
for ($caIndex=0; $caIndex -lt $caCount; $caIndex++)
{
$caIndex = $certConfig.Next();
$availableCAString += $certConfig.GetField($FieldName) + "`n"
}
# HRA Registry Path where CA servers are added
$key = "SOFTWARE\Microsoft\HCS\CAServers"
$type = [Microsoft.Win32.RegistryHive]::LocalMachine
$regKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($type, $Srv)
$regKey1 = $regKey.OpenSubKey($key)
if($regKey1)
{
# For each CA configured, a registry key exists
Foreach($sub in $regKey1.GetSubKeyNames())
{
$keySub = $key + "\" + $sub
$regKeySub = $regKey.OpenSubKey($keySub)
# Check if any Value name is "Server"
# This should contain the CA path
Foreach($val in $regKeySub.GetValueNames())
{
if($val -eq "Server")
{
$configuredCAString += $regKeySub.GetValue("$val") + "`n"
}
}
}
}
# for each CA Configured on machine, check if it exists in available CAs
$ArrayOfAvailableCA = $availableCAString.Split("`n");
foreach($availableCA in $ArrayOfAvailableCA)
{
$ArrayOfConfiguredCA = $configuredCAString.Split("`n");
foreach($configuredCA in $ArrayOfConfiguredCA)
{
if($availableCA -ne "" -and
$configuredCA -ne "")
{
$availableCAwithSlash = "\\" + $availableCA
if($availableCA -eq $configuredCA -or
$availableCAwithSlash -eq $configuredCA)
{
$CAReachable = $true
break
}
}
}
if($CAReachable -eq $true)
{
break
}
}
# Return the result of the rule
return $CAReachable
}
# Function Description:
# Checks if IIS is configured to accept Http and Https requests
#
# Arguments:
# $IISCfg: IIS configuration file
#
# Return Value:
# ok - HRA accepts both HTTPS and HTTP communications
# error - HRA does not accept both HTTPS and HTTP communications
# warning - HRA accepts either HTTPS or HTTP communications
function DoesHraAcceptsHttpHttps($IISCfg)
{
# Read the IIS configuration file and goto the appropriate node
$iisConfigNode = $IISCfg.configuration.'system.applicationHost'.sites.site
$resultHttps = $false
$resultHttp = $false
if($iisConfigNode)
{
$resultHttps = $true
$resultHttp = $true
# Among all configured websites, look for HRA
foreach($iisSite in $iisConfigNode)
{
$foundHRASite = 0
$iisApplication = $iisSite.application
foreach($_ in $iisApplication)
{
if($_.path -eq '/DomainHRA' -or
$_.path -eq '/NonDomainHRA')
{
$foundHRASite = 1
}
}
# If HRA web-site is found, check if https traffic is accepted
if($foundHRASite -eq 1)
{
$flagHraAcceptsHttp = 0
$flagHraAcceptsHttps = 0
$iisSiteBinding = $iisSite.bindings.binding
foreach($_ in $iisSiteBinding)
{
if($_.protocol -eq 'http')
{
$flagHraAcceptsHttp = 1
}
if($_.protocol -eq 'https')
{
$flagHraAcceptsHttps = 1
}
}
if($flagHraAcceptsHttps -eq 0)
{
# HRA website does not accept Https request
$resultHttps = $false
}
if($flagHraAcceptsHttp -eq 0)
{
# HRA website does not accept Http request
$resultHttp = $false
}
}
} #endof foreach($iisSite in $iisConfigNode)
} #endof if($iisConfigNode)
if($resultHttps -and $resultHttp)
{
return "ok"
}
if(!$resultHttps -and !$resultHttp)
{
return "error"
}
if(!$resultHttps -or !$resultHttp)
{
return "warning"
}
return "ok"
}
# Function Description:
# Ensure that the port is enabled and allows the incomming traffic
#
# Arguments:
# $InputText: output of "netsh advf firewall"
#
# Return Value:
# $RulePortEnabled: returns "true" if the port is enabled
#
function IsPortEnabled($InputText)
{
$result = $false
$ruleEnabled = $FALSE
$ruleAction = $FALSE
# Split each line of netsh output
# Checks the value of "Enabled" and "Action" keywords in input text
foreach($_ in $InputText)
{
$abcd = $_.Split(" ", [StringSplitOptions]::RemoveEmptyEntries)
# Ensure 'Enabled:' is set to "Yes"
if($abcd[0] -eq "Enabled:")
{
$ruleEnabled = $FALSE
if($abcd[1] -eq "Yes")
{
$ruleEnabled = $TRUE
}
}
# Ensure 'Action:' is set to "Allow"
if($abcd[0] -eq "Action:")
{
$ruleAction = $FALSE
if($abcd[1] -eq "Allow")
{
$ruleAction = $TRUE
}
}
}
$result = $ruleEnabled -and $ruleAction
# Return the result of the rule
return $result
}
# Function Description:
# Checks if Server’s firewall settings has exemption for both http and
# https traffic
#
# Arguments:
# None
#
# Return Value:
# Boolean. true if Server’s firewall settings has exemption for both http
# and https traffic, false otherwise
#
function CheckFirewallExemptionForHttpHttps()
{
$httpPortEnabled = (Get-NetFirewallRule | Where-Object {$_.InstanceID -Eq "IIS-WebServerRole-HTTP-In-TCP" -and $_.Enabled -Eq "True"}) -ne $null
$httpsPortEnabled = (Get-NetFirewallRule | Where-Object {$_.InstanceID -Eq "IIS-WebServerRole-HTTPS-In-TCP" -and $_.Enabled -Eq "True"}) -ne $null
# Return the result of the rule
if($httpsPortEnabled -and $httpPortEnabled)
{
return "ok"
}
if(!$httpsPortEnabled -and !$httpPortEnabled)
{
return "error"
}
if(!$httpsPortEnabled -or !$httpPortEnabled)
{
return "warning"
}
return "ok"
}
# Function Description:
# Checks if IIS server role is installed on HRA server
#
# Arguments:
# None
#
# Return Value:
# Boolean. true if IIS server role is installed on HRA server,
# false otherwise
#
function IsIISComponentsInstalled()
{
$boolIISComponentsInstalled = $false
# Initialize to perform querying Role information
RoleQueryInitialize
# Check if IIS is installed
$boolIISComponentsInstalled = IsRoleInstalled "Web-Server"
# Role Information obtained.
RoleQueryShutdown
return $boolIISComponentsInstalled
}
# Function Description:
# Ensures that the certificate issued by StandAlone CA Server should be greater
# than 20 minutes and less than 8 hours
#
# Arguments:
# None
#
# Return Value:
# Boolean. true if certificate lifetime is within the range,
# false otherwise
#
function CheckCertificateLifeTime
{
#Run this rule only when standAlone CA is locally configured
$result = $true
# Read the registry
$certLifeTime = (get-itemProperty HKLM:\Software\Microsoft\HCS\CAServers).CertificateLifeTime
if($certLifeTime)
{
# Ensure the certificate lifetime is atleast 20 minutes and not greater
# than 24 hours
$result = ($certLifeTime -ge 20 -and $certLifeTime -le 1440)
}
# Return the result of the rule
return $result
}
# Function Description:
# This function appends the results to the xml file
#
# Arguments:
# xml file which contains the results of rules
#
# Return Value:
# None
#
function AppendToXML($document, $boolResult, $xmlNode)
{
if ($boolResult -eq $true)
{
$document.CreateNavigator().AppendChild("<$xmlNode>true$xmlNode>")
}
else
{
$document.CreateNavigator().AppendChild("<$xmlNode>false$xmlNode>")
}
}
# Function Description:
# This function creates a temp directory under the OS temp directory.
# The directory is unique to the current session.
#
# Arguments:
# None
#
# Return Value:
# The path to the new temp directory.
#
function CreateTempSessionDir()
{
$ticks = (Get-Date).Ticks
$sessionName = [String]::Format("BPA_NPAS_{0}", $ticks)
$tempSessionDir = Join-Path -Path $env:TEMP -ChildPath $sessionName
[Void](New-Item -Path $tempSessionDir -ItemType 'directory')
return $tempSessionDir
}
# Function Description:
# This function creates an nps configuration file using sdohlp.dll
# Sdo generates a configuration file (xml) in a temp directory and the xml
# is read. The directory and the temporary xml file are deleted before
# the function exits.
#
# Arguments:
# None
#
# Return Value:
# An xml that was created using the configuration file that was generated by sdo.
#
function GetNpsConfiguration()
{
$tempSessionDir = $null
try
{
# Create temp directory for the nps configuration
$tempSessionDir = CreateTempSessionDir
# export nps configuration
$iaxXmlPath = Join-Path -Path $tempSessionDir -ChildPath 'ias.xml'
$sdoType = [Type]::GetTypeFromCLSID("e9970fa4-b6aa-11d9-b032-000d56c25c27")
$sdo = [Activator]::CreateInstance($sdoType)
[Void]$sdo.Initialize($null)
[Void]$sdo.GetIasService()
[Void]$sdo.ExportConfiguration($null, $iaxXmlPath)
# read nps configuration
[xml] $xdNpsSvrCfg = Get-Content -Encoding UTF8 $iaxXmlPath
return $xdNpsSvrCfg
}
catch
{
throw $_.exception
}
finally
{
if ($tempSessionDir -ne $null)
{
Remove-Item -Path $tempSessionDir -Recurse
}
}
}
# Function Description:
# Entering function for NPS rules
# This function calls NPS rules only when NPS component is installed
# The rule results are appended to the xml file
#
# Arguments:
# xml file which contains the results of rules
#
# Return Value:
# None
#
function NPSMain($document)
{
# Initialize to perform querying Role information
RoleQueryInitialize
# Check if Certificate Authority is installed
$ADCSCertAuthorityInstalled = IsRoleInstalled "ADCS-Cert-Authority"
# Check if NPS is installed
$isNPSInstalled = IsRoleInstalled "NPAS-Policy-Server"
# Role Information obtained.
RoleQueryShutdown
if($isNPSInstalled -eq $true)
{
# Get NPS configuration
[xml] $xdNpsSvrCfg = GetNpsConfiguration
# Call the Rules and Append the results to XML file
$boolResult = IsNpsServiceStatus
AppendToXML $document $boolResult "NpsServiceStatus"
$boolResult = IsNpsCrpEnabled($xdNpsSvrCfg)
AppendToXML $document $boolResult "NpsCrpEnabled"
$boolResult = IsNpsNetworkPolicyEnabled($xdNpsSvrCfg)
AppendToXML $document $boolResult "NpsNetworkPolicyEnabled"
$npsAuthenticationMethodText = CheckNpsAuthenticationMethod($xdNpsSvrCfg)
if($npsAuthenticationMethodText.Length -gt 0)
{
$document.CreateNavigator().AppendChild($npsAuthenticationMethodText)
}
$boolResult = IsNasRunningLocally($xdNpsSvrCfg)
AppendToXML $document $boolResult "NasRunningLocally"
}
}
# Function Description:
# Entering function for HRA rules
# This function calls HRA rules only when HRA component is installed
# The rule results are appended to the xml file
#
# Arguments:
# xml file which contains the results of rules
#
# Return Value:
# None
#
function HRAMain($document)
{
# Initialize to perform querying Role information
RoleQueryInitialize
# Check if Certificate Authority is installed
$ADCSCertAuthorityInstalled = IsRoleInstalled "ADCS-Cert-Authority"
# Check if HRA is installed
$isHRAInstalled = IsRoleInstalled "NPAS-Health"
# Role Information obtained.
RoleQueryShutdown
if($isHRAInstalled -eq $true)
{
# Call the Rules and Append the results to XML file
$boolResult = IsAtleastOneCAReachable
AppendToXML $document $boolResult "AtleastOneCAConfigured"
# Get IIS configuration
[xml] $IISCfg = get-content -Encoding UTF8 $env:windir\system32\inetsrv\config\applicationHost.config
if($IISCfg)
{
$stringResult = DoesHraAcceptsHttpHttps($IISCfg)
$document.CreateNavigator().AppendChild("$stringResult")
}
$StringResult = CheckFirewallExemptionForHttpHttps
$document.CreateNavigator().AppendChild("$stringResult")
$boolResult = IsIISComponentsInstalled
AppendToXML $document $boolResult "IISComponentsInstalled"
#Run this rule only when standAlone CA is locally configured
if(IsStandAloneCARunning($ADCSCertAuthorityInstalled) -eq $true)
{
$boolResult = CheckCertificateLifeTime
AppendToXML $document $boolResult "CertificateLifeTime"
}
}
}
#
# ------------------
# FUNCTIONS - END
# ------------------
#
#
# ------------------------
# SCRIPT MAIN BODY - START
# ------------------------
#
# Set the Target Namespace to be used by XML
$tns="http://schemas.microsoft.com/mbca/models/NPAS/2009/11"
NPSMain $NPSNode
HRAMain $HRANode
$doc
#
# ------------------------
# SCRIPT MAIN BODY - END
# ------------------------
#