mirror of
https://github.com/MicrosoftDocs/windows-itpro-docs.git
synced 2025-05-13 22:07:22 +00:00
Merge pull request #542 from jotob-msft/cred_guard_new_content
Add Logon cached password verifiers text
This commit is contained in:
commit
bba3178f4f
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
title: Scenarios not protected by Credential Guard (Windows 10)
|
title: Credential Guard protection limits (Windows 10)
|
||||||
description: Scenarios not protected by Credential Guard in Windows 10.
|
description: Scenarios not protected by Credential Guard in Windows 10.
|
||||||
ms.prod: w10
|
ms.prod: w10
|
||||||
ms.mktglfcycl: explore
|
ms.mktglfcycl: explore
|
||||||
@ -9,7 +9,7 @@ localizationpriority: high
|
|||||||
author: brianlic-msft
|
author: brianlic-msft
|
||||||
---
|
---
|
||||||
|
|
||||||
# Scenarios not protected by Credential Guard
|
# Credential Guard protection limits
|
||||||
|
|
||||||
**Applies to**
|
**Applies to**
|
||||||
- Windows 10
|
- Windows 10
|
||||||
@ -31,7 +31,12 @@ Some ways to store credentials are not protected by Credential Guard, including:
|
|||||||
- When Credential Guard is enabled, neither Digest nor CredSSP have access to users' logon credentials. This implies no Single Sign-On use for these protocols.
|
- When Credential Guard is enabled, neither Digest nor CredSSP have access to users' logon credentials. This implies no Single Sign-On use for these protocols.
|
||||||
- Supplied credentials for NTLM authentication are not protected. If a user is prompted for and enters credentials for NTLM authentication, these credentials are vulnerable to be read from LSASS memory. Note that these same credentials are vulnerable to key loggers as well.
|
- Supplied credentials for NTLM authentication are not protected. If a user is prompted for and enters credentials for NTLM authentication, these credentials are vulnerable to be read from LSASS memory. Note that these same credentials are vulnerable to key loggers as well.
|
||||||
|
|
||||||
For further information, see video: [Credentials Protected by Credential Guard](https://mva.microsoft.com/en-us/training-courses/deep-dive-into-credential-guard-16651?l=pdc37LJyC_1204300474)
|
>[!NOTE]
|
||||||
|
When Credential Guard is deployed on a VM, Credential Guard protects secrets from attacks inside the VM. However, it does not provide additional protection from privileged system attacks originating from the host.
|
||||||
|
|
||||||
|
>[!NOTE]
|
||||||
|
Windows logon cached password verifiers (commonly called "cached credentials")
|
||||||
|
do not qualify as credentials because they cannot be presented to another computer for authentication, and can only be used locally to verify credentials. They are stored in the registry on the local computer and provide validation for credentials when a domain-joined computer cannot connect to AD DS during user logon. These “cached logons”, or more specifically, cached domain account information, can be managed using the security policy setting **Interactive logon: Number of previous logons to cache** if a domain controller is not available.
|
||||||
|
|
||||||
## Additional mitigations
|
## Additional mitigations
|
||||||
|
|
||||||
@ -41,7 +46,7 @@ Credential Guard can provide mitigations against attacks on derived credentials
|
|||||||
|
|
||||||
Credential theft attacks allow the attacker to steal secrets from one device and use them from another device. If a user can sign on to multiple devices then any device could be used to steal credentials. How do you ensure that users only sign on using devices that have Credential Guard enabled? By deploying authentication policies that restrict them to specific domain-joined devices that have been configured with Credential Guard. For the domain controller to know what device a user is signing on from, Kerberos armoring must be used.
|
Credential theft attacks allow the attacker to steal secrets from one device and use them from another device. If a user can sign on to multiple devices then any device could be used to steal credentials. How do you ensure that users only sign on using devices that have Credential Guard enabled? By deploying authentication policies that restrict them to specific domain-joined devices that have been configured with Credential Guard. For the domain controller to know what device a user is signing on from, Kerberos armoring must be used.
|
||||||
|
|
||||||
### Kerberos armoring
|
#### Kerberos armoring
|
||||||
|
|
||||||
Kerberos armoring is part of RFC 6113. When a device supports Kerberos armoring, its TGT is used to protect the user's proof of possession which can mitigate offline dictionary attacks. Kerberos armoring also provides the additional benefit of signed KDC errors this mitigates tampering which can result in things such as downgrade attacks.
|
Kerberos armoring is part of RFC 6113. When a device supports Kerberos armoring, its TGT is used to protect the user's proof of possession which can mitigate offline dictionary attacks. Kerberos armoring also provides the additional benefit of signed KDC errors this mitigates tampering which can result in things such as downgrade attacks.
|
||||||
|
|
||||||
@ -51,7 +56,7 @@ Kerberos armoring is part of RFC 6113. When a device supports Kerberos armoring,
|
|||||||
- All the domain controllers in these domains must be configured to support Kerberos armoring. Set the **KDC support for claims, compound authentication, and Kerberos armoring** Group Policy setting to either **Supported** or **Always provide claims**.
|
- All the domain controllers in these domains must be configured to support Kerberos armoring. Set the **KDC support for claims, compound authentication, and Kerberos armoring** Group Policy setting to either **Supported** or **Always provide claims**.
|
||||||
- All the devices with Credential Guard that the users will be restricted to must be configured to support Kerberos armoring. Enable the **Kerberos client support for claims, compound authentication and Kerberos armoring** Group Policy settings under **Computer Configuration** -> **Administrative Templates** -> **System** -> **Kerberos**.
|
- All the devices with Credential Guard that the users will be restricted to must be configured to support Kerberos armoring. Enable the **Kerberos client support for claims, compound authentication and Kerberos armoring** Group Policy settings under **Computer Configuration** -> **Administrative Templates** -> **System** -> **Kerberos**.
|
||||||
|
|
||||||
### Protecting domain-joined device secrets
|
#### Protecting domain-joined device secrets
|
||||||
|
|
||||||
Since domain-joined devices also use shared secrets for authentication, attackers can steal those secrets as well. By deploying device certificates with Credential Guard, the private key can be protected. Then authentication policies can require that users sign on devices that authenticate using those certificates. This prevents shared secrets stolen from the device to be used with stolen user credentials to sign on as the user.
|
Since domain-joined devices also use shared secrets for authentication, attackers can steal those secrets as well. By deploying device certificates with Credential Guard, the private key can be protected. Then authentication policies can require that users sign on devices that authenticate using those certificates. This prevents shared secrets stolen from the device to be used with stolen user credentials to sign on as the user.
|
||||||
|
|
||||||
@ -63,7 +68,7 @@ Domain-joined device certificate authentication has the following requirements:
|
|||||||
- Windows 10 devices have the CA issuing the domain controller certificates in the enterprise store.
|
- Windows 10 devices have the CA issuing the domain controller certificates in the enterprise store.
|
||||||
- A process is established to ensure the identity and trustworthiness of the device in a similar manner as you would establish the identity and trustworthiness of a user before issuing them a smartcard.
|
- A process is established to ensure the identity and trustworthiness of the device in a similar manner as you would establish the identity and trustworthiness of a user before issuing them a smartcard.
|
||||||
|
|
||||||
#### Deploying domain-joined device certificates
|
##### Deploying domain-joined device certificates
|
||||||
|
|
||||||
To guarantee that certificates with the required issuance policy are only installed on the devices these users must use, they must be deployed manually on each device. The same security procedures used for issuing smart cards to users should be applied to device certificates.
|
To guarantee that certificates with the required issuance policy are only installed on the devices these users must use, they must be deployed manually on each device. The same security procedures used for issuing smart cards to users should be applied to device certificates.
|
||||||
|
|
||||||
@ -95,7 +100,7 @@ CertReq -EnrollCredGuardCert MachineAuthentication
|
|||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> You must restart the device after enrolling the machine authentication certificate.
|
> You must restart the device after enrolling the machine authentication certificate.
|
||||||
|
|
||||||
#### How a certificate issuance policy can be used for access control
|
##### How a certificate issuance policy can be used for access control
|
||||||
|
|
||||||
Beginning with the Windows Server 2008 R2 domain functional level, domain controllers support for authentication mechanism assurance provides a way to map certificate issuance policy OIDs to universal security groups. Windows Server 2012 domain controllers with claim support can map them to claims. To learn more about authentication mechanism assurance, see [Authentication Mechanism Assurance for AD DS in Windows Server 2008 R2 Step-by-Step Guide](https://technet.microsoft.com/en-us/library/dd378897(v=ws.10).aspx) on TechNet.
|
Beginning with the Windows Server 2008 R2 domain functional level, domain controllers support for authentication mechanism assurance provides a way to map certificate issuance policy OIDs to universal security groups. Windows Server 2012 domain controllers with claim support can map them to claims. To learn more about authentication mechanism assurance, see [Authentication Mechanism Assurance for AD DS in Windows Server 2008 R2 Step-by-Step Guide](https://technet.microsoft.com/en-us/library/dd378897(v=ws.10).aspx) on TechNet.
|
||||||
|
|
||||||
@ -117,7 +122,7 @@ Beginning with the Windows Server 2008 R2 domain functional level, domain contro
|
|||||||
.\set-IssuancePolicyToGroupLink.ps1 –IssuancePolicyName:"<name of issuance policy>" –groupOU:"<Name of OU to create>" –groupName:”<name of Universal security group to create>"
|
.\set-IssuancePolicyToGroupLink.ps1 –IssuancePolicyName:"<name of issuance policy>" –groupOU:"<Name of OU to create>" –groupName:”<name of Universal security group to create>"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Restricting user sign on
|
#### Restricting user sign on
|
||||||
|
|
||||||
So we now have completed the following:
|
So we now have completed the following:
|
||||||
|
|
||||||
@ -146,12 +151,529 @@ Authentication policies have the following requirements:
|
|||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> When the authentication policy enforces policy restrictions, users will not be able to sign on using devices that do not have a certificate with the appropriate issuance policy deployed. This applies to both local and remote sign on scenarios. Therefore, it is strongly recommended to first only audit policy restrictions to ensure you don't have unexpected failures.
|
> When the authentication policy enforces policy restrictions, users will not be able to sign on using devices that do not have a certificate with the appropriate issuance policy deployed. This applies to both local and remote sign on scenarios. Therefore, it is strongly recommended to first only audit policy restrictions to ensure you don't have unexpected failures.
|
||||||
|
|
||||||
#### Discovering authentication failures due to authentication policies
|
##### Discovering authentication failures due to authentication policies
|
||||||
|
|
||||||
To make tracking authentication failures due to authentication policies easier, an operational log exists with just those events. To enable the logs on the domain controllers, in Event Viewer, navigate to **Applications and Services Logs\\Microsoft\\Windows\\Authentication, right-click AuthenticationPolicyFailures-DomainController**, and then click **Enable Log**.
|
To make tracking authentication failures due to authentication policies easier, an operational log exists with just those events. To enable the logs on the domain controllers, in Event Viewer, navigate to **Applications and Services Logs\\Microsoft\\Windows\\Authentication, right-click AuthenticationPolicyFailures-DomainController**, and then click **Enable Log**.
|
||||||
|
|
||||||
To learn more about authentication policy events, see [Authentication Policies and Authentication Policy Silos](https://technet.microsoft.com/en-us/library/dn486813(v=ws.11).aspx).
|
To learn more about authentication policy events, see [Authentication Policies and Authentication Policy Silos](https://technet.microsoft.com/en-us/library/dn486813(v=ws.11).aspx).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Appendix: Scripts
|
||||||
|
|
||||||
|
|
||||||
|
Here is a list of scripts mentioned in this topic.
|
||||||
|
|
||||||
|
#### <a href="" id="bkmk-getscript"></a>Get the available issuance policies on the certificate authority
|
||||||
|
|
||||||
|
Save this script file as get-IssuancePolicy.ps1.
|
||||||
|
|
||||||
|
``` syntax
|
||||||
|
#######################################
|
||||||
|
## Parameters to be defined ##
|
||||||
|
## by the user ##
|
||||||
|
#######################################
|
||||||
|
Param (
|
||||||
|
$Identity,
|
||||||
|
$LinkedToGroup
|
||||||
|
)
|
||||||
|
#######################################
|
||||||
|
## Strings definitions ##
|
||||||
|
#######################################
|
||||||
|
Data getIP_strings {
|
||||||
|
# culture="en-US"
|
||||||
|
ConvertFrom-StringData -stringdata @'
|
||||||
|
help1 = This command can be used to retrieve all available Issuance Policies in a forest. The forest of the currently logged on user is targeted.
|
||||||
|
help2 = Usage:
|
||||||
|
help3 = The following parameter is mandatory:
|
||||||
|
help4 = -LinkedToGroup:<yes|no|all>
|
||||||
|
help5 = "yes" will return only Issuance Policies that are linked to groups. Checks that the linked Issuance Policies are linked to valid groups.
|
||||||
|
help6 = "no" will return only Issuance Policies that are not currently linked to any group.
|
||||||
|
help7 = "all" will return all Issuance Policies defined in the forest. Checks that the linked Issuance policies are linked to valid groups.
|
||||||
|
help8 = The following parameter is optional:
|
||||||
|
help9 = -Identity:<Name, Distinguished Name or Display Name of the Issuance Policy that you want to retrieve>. If you specify an identity, the option specified in the "-LinkedToGroup" parameter is ignored.
|
||||||
|
help10 = Output: This script returns the Issuance Policy objects meeting the criteria defined by the above parameters.
|
||||||
|
help11 = Examples:
|
||||||
|
errorIPNotFound = Error: no Issuance Policy could be found with Identity "{0}"
|
||||||
|
ErrorNotSecurity = Error: Issuance Policy "{0}" is linked to group "{1}" which is not of type "Security".
|
||||||
|
ErrorNotUniversal = Error: Issuance Policy "{0}" is linked to group "{1}" whose scope is not "Universal".
|
||||||
|
ErrorHasMembers = Error: Issuance Policy "{0}" is linked to group "{1}" which has a non-empty membership. The group has the following members:
|
||||||
|
LinkedIPs = The following Issuance Policies are linked to groups:
|
||||||
|
displayName = displayName : {0}
|
||||||
|
Name = Name : {0}
|
||||||
|
dn = distinguishedName : {0}
|
||||||
|
InfoName = Linked Group Name: {0}
|
||||||
|
InfoDN = Linked Group DN: {0}
|
||||||
|
NonLinkedIPs = The following Issuance Policies are NOT linked to groups:
|
||||||
|
'@
|
||||||
|
}
|
||||||
|
##Import-LocalizedData getIP_strings
|
||||||
|
import-module ActiveDirectory
|
||||||
|
#######################################
|
||||||
|
## Help ##
|
||||||
|
#######################################
|
||||||
|
function Display-Help {
|
||||||
|
""
|
||||||
|
$getIP_strings.help1
|
||||||
|
""
|
||||||
|
$getIP_strings.help2
|
||||||
|
""
|
||||||
|
$getIP_strings.help3
|
||||||
|
" " + $getIP_strings.help4
|
||||||
|
" " + $getIP_strings.help5
|
||||||
|
" " + $getIP_strings.help6
|
||||||
|
" " + $getIP_strings.help7
|
||||||
|
""
|
||||||
|
$getIP_strings.help8
|
||||||
|
" " + $getIP_strings.help9
|
||||||
|
""
|
||||||
|
$getIP_strings.help10
|
||||||
|
""
|
||||||
|
""
|
||||||
|
$getIP_strings.help11
|
||||||
|
" " + '$' + "myIPs = .\get-IssuancePolicy.ps1 -LinkedToGroup:All"
|
||||||
|
" " + '$' + "myLinkedIPs = .\get-IssuancePolicy.ps1 -LinkedToGroup:yes"
|
||||||
|
" " + '$' + "myIP = .\get-IssuancePolicy.ps1 -Identity:""Medium Assurance"""
|
||||||
|
""
|
||||||
|
}
|
||||||
|
$root = get-adrootdse
|
||||||
|
$domain = get-addomain -current loggedonuser
|
||||||
|
$configNCDN = [String]$root.configurationNamingContext
|
||||||
|
if ( !($Identity) -and !($LinkedToGroup) ) {
|
||||||
|
display-Help
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if ($Identity) {
|
||||||
|
$OIDs = get-adobject -Filter {(objectclass -eq "msPKI-Enterprise-Oid") -and ((name -eq $Identity) -or (displayname -eq $Identity) -or (distinguishedName -like $Identity)) } -searchBase $configNCDN -properties *
|
||||||
|
if ($OIDs -eq $null) {
|
||||||
|
$errormsg = $getIP_strings.ErrorIPNotFound -f $Identity
|
||||||
|
write-host $errormsg -ForegroundColor Red
|
||||||
|
}
|
||||||
|
foreach ($OID in $OIDs) {
|
||||||
|
if ($OID."msDS-OIDToGroupLink") {
|
||||||
|
# In case the Issuance Policy is linked to a group, it is good to check whether there is any problem with the mapping.
|
||||||
|
$groupDN = $OID."msDS-OIDToGroupLink"
|
||||||
|
$group = get-adgroup -Identity $groupDN
|
||||||
|
$groupName = $group.Name
|
||||||
|
# Analyze the group
|
||||||
|
if ($group.groupCategory -ne "Security") {
|
||||||
|
$errormsg = $getIP_strings.ErrorNotSecurity -f $Identity, $groupName
|
||||||
|
write-host $errormsg -ForegroundColor Red
|
||||||
|
}
|
||||||
|
if ($group.groupScope -ne "Universal") {
|
||||||
|
$errormsg = $getIP_strings.ErrorNotUniversal -f $Identity, $groupName
|
||||||
|
write-host $errormsg -ForegroundColor Red
|
||||||
|
}
|
||||||
|
$members = Get-ADGroupMember -Identity $group
|
||||||
|
if ($members) {
|
||||||
|
$errormsg = $getIP_strings.ErrorHasMembers -f $Identity, $groupName
|
||||||
|
write-host $errormsg -ForegroundColor Red
|
||||||
|
foreach ($member in $members) {
|
||||||
|
write-host " " $member -ForeGroundColor Red
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $OIDs
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if (($LinkedToGroup -eq "yes") -or ($LinkedToGroup -eq "all")) {
|
||||||
|
$LDAPFilter = "(&(objectClass=msPKI-Enterprise-Oid)(msDS-OIDToGroupLink=*)(flags=2))"
|
||||||
|
$LinkedOIDs = get-adobject -searchBase $configNCDN -LDAPFilter $LDAPFilter -properties *
|
||||||
|
write-host ""
|
||||||
|
write-host "*****************************************************"
|
||||||
|
write-host $getIP_strings.LinkedIPs
|
||||||
|
write-host "*****************************************************"
|
||||||
|
write-host ""
|
||||||
|
if ($LinkedOIDs -ne $null){
|
||||||
|
foreach ($OID in $LinkedOIDs) {
|
||||||
|
# Display basic information about the Issuance Policies
|
||||||
|
""
|
||||||
|
$getIP_strings.displayName -f $OID.displayName
|
||||||
|
$getIP_strings.Name -f $OID.Name
|
||||||
|
$getIP_strings.dn -f $OID.distinguishedName
|
||||||
|
# Get the linked group.
|
||||||
|
$groupDN = $OID."msDS-OIDToGroupLink"
|
||||||
|
$group = get-adgroup -Identity $groupDN
|
||||||
|
$getIP_strings.InfoName -f $group.Name
|
||||||
|
$getIP_strings.InfoDN -f $groupDN
|
||||||
|
# Analyze the group
|
||||||
|
$OIDName = $OID.displayName
|
||||||
|
$groupName = $group.Name
|
||||||
|
if ($group.groupCategory -ne "Security") {
|
||||||
|
$errormsg = $getIP_strings.ErrorNotSecurity -f $OIDName, $groupName
|
||||||
|
write-host $errormsg -ForegroundColor Red
|
||||||
|
}
|
||||||
|
if ($group.groupScope -ne "Universal") {
|
||||||
|
$errormsg = $getIP_strings.ErrorNotUniversal -f $OIDName, $groupName
|
||||||
|
write-host $errormsg -ForegroundColor Red
|
||||||
|
}
|
||||||
|
$members = Get-ADGroupMember -Identity $group
|
||||||
|
if ($members) {
|
||||||
|
$errormsg = $getIP_strings.ErrorHasMembers -f $OIDName, $groupName
|
||||||
|
write-host $errormsg -ForegroundColor Red
|
||||||
|
foreach ($member in $members) {
|
||||||
|
write-host " " $member -ForeGroundColor Red
|
||||||
|
}
|
||||||
|
}
|
||||||
|
write-host ""
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
write-host "There are no issuance policies that are mapped to a group"
|
||||||
|
}
|
||||||
|
if ($LinkedToGroup -eq "yes") {
|
||||||
|
return $LinkedOIDs
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (($LinkedToGroup -eq "no") -or ($LinkedToGroup -eq "all")) {
|
||||||
|
$LDAPFilter = "(&(objectClass=msPKI-Enterprise-Oid)(!(msDS-OIDToGroupLink=*))(flags=2))"
|
||||||
|
$NonLinkedOIDs = get-adobject -searchBase $configNCDN -LDAPFilter $LDAPFilter -properties *
|
||||||
|
write-host ""
|
||||||
|
write-host "*********************************************************"
|
||||||
|
write-host $getIP_strings.NonLinkedIPs
|
||||||
|
write-host "*********************************************************"
|
||||||
|
write-host ""
|
||||||
|
if ($NonLinkedOIDs -ne $null) {
|
||||||
|
foreach ($OID in $NonLinkedOIDs) {
|
||||||
|
# Display basic information about the Issuance Policies
|
||||||
|
write-host ""
|
||||||
|
$getIP_strings.displayName -f $OID.displayName
|
||||||
|
$getIP_strings.Name -f $OID.Name
|
||||||
|
$getIP_strings.dn -f $OID.distinguishedName
|
||||||
|
write-host ""
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
write-host "There are no issuance policies which are not mapped to groups"
|
||||||
|
}
|
||||||
|
if ($LinkedToGroup -eq "no") {
|
||||||
|
return $NonLinkedOIDs
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
> [!NOTE]
|
||||||
|
> If you're having trouble running this script, try replacing the single quote after the ConvertFrom-StringData parameter.
|
||||||
|
|
||||||
|
#### <a href="" id="bkmk-setscript"></a>Link an issuance policy to a group
|
||||||
|
|
||||||
|
Save the script file as set-IssuancePolicyToGroupLink.ps1.
|
||||||
|
|
||||||
|
``` syntax
|
||||||
|
#######################################
|
||||||
|
## Parameters to be defined ##
|
||||||
|
## by the user ##
|
||||||
|
#######################################
|
||||||
|
Param (
|
||||||
|
$IssuancePolicyName,
|
||||||
|
$groupOU,
|
||||||
|
$groupName
|
||||||
|
)
|
||||||
|
#######################################
|
||||||
|
## Strings definitions ##
|
||||||
|
#######################################
|
||||||
|
Data ErrorMsg {
|
||||||
|
# culture="en-US"
|
||||||
|
ConvertFrom-StringData -stringdata @'
|
||||||
|
help1 = This command can be used to set the link between a certificate issuance policy and a universal security group.
|
||||||
|
help2 = Usage:
|
||||||
|
help3 = The following parameters are required:
|
||||||
|
help4 = -IssuancePolicyName:<name or display name of the issuance policy that you want to link to a group>
|
||||||
|
help5 = -groupName:<name of the group you want to link the issuance policy to>. If no name is specified, any existing link to a group is removed from the Issuance Policy.
|
||||||
|
help6 = The following parameter is optional:
|
||||||
|
help7 = -groupOU:<Name of the Organizational Unit dedicated to the groups which are linked to issuance policies>. If this parameter is not specified, the group is looked for or created in the Users container.
|
||||||
|
help8 = Examples:
|
||||||
|
help9 = This command will link the issuance policy whose display name is "High Assurance" to the group "HighAssuranceGroup" in the Organizational Unit "OU_FOR_IPol_linked_groups". If the group or the Organizational Unit do not exist, you will be prompted to create them.
|
||||||
|
help10 = This command will unlink the issuance policy whose name is "402.164959C40F4A5C12C6302E31D5476062" from any group.
|
||||||
|
MultipleIPs = Error: Multiple Issuance Policies with name or display name "{0}" were found in the subtree of "{1}"
|
||||||
|
NoIP = Error: no issuance policy with name or display name "{0}" could be found in the subtree of "{1}".
|
||||||
|
IPFound = An Issuance Policy with name or display name "{0}" was successfully found: {1}
|
||||||
|
MultipleOUs = Error: more than 1 Organizational Unit with name "{0}" could be found in the subtree of "{1}".
|
||||||
|
confirmOUcreation = Warning: The Organizational Unit that you specified does not exist. Do you want to create it?
|
||||||
|
OUCreationSuccess = Organizational Unit "{0}" successfully created.
|
||||||
|
OUcreationError = Error: Organizational Unit "{0}" could not be created.
|
||||||
|
OUFoundSuccess = Organizational Unit "{0}" was successfully found.
|
||||||
|
multipleGroups = Error: More than one group with name "{0}" was found in Organizational Unit "{1}".
|
||||||
|
confirmGroupCreation = Warning: The group that you specified does not exist. Do you want to create it?
|
||||||
|
groupCreationSuccess = Univeral Security group "{0}" successfully created.
|
||||||
|
groupCreationError = Error: Univeral Security group "{0}" could not be created.
|
||||||
|
GroupFound = Group "{0}" was successfully found.
|
||||||
|
confirmLinkDeletion = Warning: The Issuance Policy "{0}" is currently linked to group "{1}". Do you really want to remove the link?
|
||||||
|
UnlinkSuccess = Certificate issuance policy successfully unlinked from any group.
|
||||||
|
UnlinkError = Removing the link failed.
|
||||||
|
UnlinkExit = Exiting without removing the link from the issuance policy to the group.
|
||||||
|
IPNotLinked = The Certificate issuance policy is not currently linked to any group. If you want to link it to a group, you should specify the -groupName option when starting this script.
|
||||||
|
ErrorNotSecurity = Error: You cannot link issuance Policy "{0}" to group "{1}" because this group is not of type "Security".
|
||||||
|
ErrorNotUniversal = Error: You cannot link issuance Policy "{0}" to group "{1}" because the scope of this group is not "Universal".
|
||||||
|
ErrorHasMembers = Error: You cannot link issuance Policy "{0}" to group "{1}" because it has a non-empty membership. The group has the following members:
|
||||||
|
ConfirmLinkReplacement = Warning: The Issuance Policy "{0}" is currently linked to group "{1}". Do you really want to update the link to point to group "{2}"?
|
||||||
|
LinkSuccess = The certificate issuance policy was successfully linked to the specified group.
|
||||||
|
LinkError = The certificate issuance policy could not be linked to the specified group.
|
||||||
|
ExitNoLinkReplacement = Exiting without setting the new link.
|
||||||
|
'@
|
||||||
|
}
|
||||||
|
# import-localizeddata ErrorMsg
|
||||||
|
function Display-Help {
|
||||||
|
""
|
||||||
|
write-host $ErrorMsg.help1
|
||||||
|
""
|
||||||
|
write-host $ErrorMsg.help2
|
||||||
|
""
|
||||||
|
write-host $ErrorMsg.help3
|
||||||
|
write-host "`t" $ErrorMsg.help4
|
||||||
|
write-host "`t" $ErrorMsg.help5
|
||||||
|
""
|
||||||
|
write-host $ErrorMsg.help6
|
||||||
|
write-host "`t" $ErrorMsg.help7
|
||||||
|
""
|
||||||
|
""
|
||||||
|
write-host $ErrorMsg.help8
|
||||||
|
""
|
||||||
|
write-host $ErrorMsg.help9
|
||||||
|
".\Set-IssuancePolicyToGroupMapping.ps1 -IssuancePolicyName ""High Assurance"" -groupOU ""OU_FOR_IPol_linked_groups"" -groupName ""HighAssuranceGroup"" "
|
||||||
|
""
|
||||||
|
write-host $ErrorMsg.help10
|
||||||
|
'.\Set-IssuancePolicyToGroupMapping.ps1 -IssuancePolicyName "402.164959C40F4A5C12C6302E31D5476062" -groupName $null '
|
||||||
|
""
|
||||||
|
}
|
||||||
|
# Assumption: The group to which the Issuance Policy is going
|
||||||
|
# to be linked is (or is going to be created) in
|
||||||
|
# the domain the user running this script is a member of.
|
||||||
|
import-module ActiveDirectory
|
||||||
|
$root = get-adrootdse
|
||||||
|
$domain = get-addomain -current loggedonuser
|
||||||
|
if ( !($IssuancePolicyName) ) {
|
||||||
|
display-Help
|
||||||
|
break
|
||||||
|
}
|
||||||
|
#######################################
|
||||||
|
## Find the OID object ##
|
||||||
|
## (aka Issuance Policy) ##
|
||||||
|
#######################################
|
||||||
|
$searchBase = [String]$root.configurationnamingcontext
|
||||||
|
$OID = get-adobject -searchBase $searchBase -Filter { ((displayname -eq $IssuancePolicyName) -or (name -eq $IssuancePolicyName)) -and (objectClass -eq "msPKI-Enterprise-Oid")} -properties *
|
||||||
|
if ($OID -eq $null) {
|
||||||
|
$tmp = $ErrorMsg.NoIP -f $IssuancePolicyName, $searchBase
|
||||||
|
write-host $tmp -ForeGroundColor Red
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
elseif ($OID.GetType().IsArray) {
|
||||||
|
$tmp = $ErrorMsg.MultipleIPs -f $IssuancePolicyName, $searchBase
|
||||||
|
write-host $tmp -ForeGroundColor Red
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$tmp = $ErrorMsg.IPFound -f $IssuancePolicyName, $OID.distinguishedName
|
||||||
|
write-host $tmp -ForeGroundColor Green
|
||||||
|
}
|
||||||
|
#######################################
|
||||||
|
## Find the container of the group ##
|
||||||
|
#######################################
|
||||||
|
if ($groupOU -eq $null) {
|
||||||
|
# default to the Users container
|
||||||
|
$groupContainer = $domain.UsersContainer
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$searchBase = [string]$domain.DistinguishedName
|
||||||
|
$groupContainer = get-adobject -searchBase $searchBase -Filter { (Name -eq $groupOU) -and (objectClass -eq "organizationalUnit")}
|
||||||
|
if ($groupContainer.count -gt 1) {
|
||||||
|
$tmp = $ErrorMsg.MultipleOUs -f $groupOU, $searchBase
|
||||||
|
write-host $tmp -ForegroundColor Red
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
elseif ($groupContainer -eq $null) {
|
||||||
|
$tmp = $ErrorMsg.confirmOUcreation
|
||||||
|
write-host $tmp " ( (y)es / (n)o )" -ForegroundColor Yellow -nonewline
|
||||||
|
$userChoice = read-host
|
||||||
|
if ( ($userChoice -eq "y") -or ($userChoice -eq "yes") ) {
|
||||||
|
new-adobject -Name $groupOU -displayName $groupOU -Type "organizationalUnit" -ProtectedFromAccidentalDeletion $true -path $domain.distinguishedName
|
||||||
|
if ($?){
|
||||||
|
$tmp = $ErrorMsg.OUCreationSuccess -f $groupOU
|
||||||
|
write-host $tmp -ForegroundColor Green
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$tmp = $ErrorMsg.OUCreationError -f $groupOU
|
||||||
|
write-host $tmp -ForeGroundColor Red
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$groupContainer = get-adobject -searchBase $searchBase -Filter { (Name -eq $groupOU) -and (objectClass -eq "organizationalUnit")}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$tmp = $ErrorMsg.OUFoundSuccess -f $groupContainer.name
|
||||||
|
write-host $tmp -ForegroundColor Green
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#######################################
|
||||||
|
## Find the group ##
|
||||||
|
#######################################
|
||||||
|
if (($groupName -ne $null) -and ($groupName -ne "")){
|
||||||
|
##$searchBase = [String]$groupContainer.DistinguishedName
|
||||||
|
$searchBase = $groupContainer
|
||||||
|
$group = get-adgroup -Filter { (Name -eq $groupName) -and (objectClass -eq "group") } -searchBase $searchBase
|
||||||
|
if ($group -ne $null -and $group.gettype().isarray) {
|
||||||
|
$tmp = $ErrorMsg.multipleGroups -f $groupName, $searchBase
|
||||||
|
write-host $tmp -ForeGroundColor Red
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
elseif ($group -eq $null) {
|
||||||
|
$tmp = $ErrorMsg.confirmGroupCreation
|
||||||
|
write-host $tmp " ( (y)es / (n)o )" -ForegroundColor Yellow -nonewline
|
||||||
|
$userChoice = read-host
|
||||||
|
if ( ($userChoice -eq "y") -or ($userChoice -eq "yes") ) {
|
||||||
|
new-adgroup -samAccountName $groupName -path $groupContainer.distinguishedName -GroupScope "Universal" -GroupCategory "Security"
|
||||||
|
if ($?){
|
||||||
|
$tmp = $ErrorMsg.GroupCreationSuccess -f $groupName
|
||||||
|
write-host $tmp -ForegroundColor Green
|
||||||
|
}else{
|
||||||
|
$tmp = $ErrorMsg.groupCreationError -f $groupName
|
||||||
|
write-host $tmp -ForeGroundColor Red
|
||||||
|
break
|
||||||
|
}
|
||||||
|
$group = get-adgroup -Filter { (Name -eq $groupName) -and (objectClass -eq "group") } -searchBase $searchBase
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$tmp = $ErrorMsg.GroupFound -f $group.Name
|
||||||
|
write-host $tmp -ForegroundColor Green
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#####
|
||||||
|
## If the group is not specified, we should remove the link if any exists
|
||||||
|
#####
|
||||||
|
if ($OID."msDS-OIDToGroupLink" -ne $null) {
|
||||||
|
$tmp = $ErrorMsg.confirmLinkDeletion -f $IssuancePolicyName, $OID."msDS-OIDToGroupLink"
|
||||||
|
write-host $tmp " ( (y)es / (n)o )" -ForegroundColor Yellow -nonewline
|
||||||
|
$userChoice = read-host
|
||||||
|
if ( ($userChoice -eq "y") -or ($userChoice -eq "yes") ) {
|
||||||
|
set-adobject -Identity $OID -Clear "msDS-OIDToGroupLink"
|
||||||
|
if ($?) {
|
||||||
|
$tmp = $ErrorMsg.UnlinkSuccess
|
||||||
|
write-host $tmp -ForeGroundColor Green
|
||||||
|
}else{
|
||||||
|
$tmp = $ErrorMsg.UnlinkError
|
||||||
|
write-host $tmp -ForeGroundColor Red
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$tmp = $ErrorMsg.UnlinkExit
|
||||||
|
write-host $tmp
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$tmp = $ErrorMsg.IPNotLinked
|
||||||
|
write-host $tmp -ForeGroundColor Yellow
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#######################################
|
||||||
|
## Verify that the group is ##
|
||||||
|
## Universal, Security, and ##
|
||||||
|
## has no members ##
|
||||||
|
#######################################
|
||||||
|
if ($group.GroupScope -ne "Universal") {
|
||||||
|
$tmp = $ErrorMsg.ErrorNotUniversal -f $IssuancePolicyName, $groupName
|
||||||
|
write-host $tmp -ForeGroundColor Red
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ($group.GroupCategory -ne "Security") {
|
||||||
|
$tmp = $ErrorMsg.ErrorNotSecurity -f $IssuancePolicyName, $groupName
|
||||||
|
write-host $tmp -ForeGroundColor Red
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$members = Get-ADGroupMember -Identity $group
|
||||||
|
if ($members -ne $null) {
|
||||||
|
$tmp = $ErrorMsg.ErrorHasMembers -f $IssuancePolicyName, $groupName
|
||||||
|
write-host $tmp -ForeGroundColor Red
|
||||||
|
foreach ($member in $members) {write-host " $member.name" -ForeGroundColor Red}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#######################################
|
||||||
|
## We have verified everything. We ##
|
||||||
|
## can create the link from the ##
|
||||||
|
## Issuance Policy to the group. ##
|
||||||
|
#######################################
|
||||||
|
if ($OID."msDS-OIDToGroupLink" -ne $null) {
|
||||||
|
$tmp = $ErrorMsg.ConfirmLinkReplacement -f $IssuancePolicyName, $OID."msDS-OIDToGroupLink", $group.distinguishedName
|
||||||
|
write-host $tmp "( (y)es / (n)o )" -ForegroundColor Yellow -nonewline
|
||||||
|
$userChoice = read-host
|
||||||
|
if ( ($userChoice -eq "y") -or ($userChoice -eq "yes") ) {
|
||||||
|
$tmp = @{'msDS-OIDToGroupLink'= $group.DistinguishedName}
|
||||||
|
set-adobject -Identity $OID -Replace $tmp
|
||||||
|
if ($?) {
|
||||||
|
$tmp = $Errormsg.LinkSuccess
|
||||||
|
write-host $tmp -Foreground Green
|
||||||
|
}else{
|
||||||
|
$tmp = $ErrorMsg.LinkError
|
||||||
|
write-host $tmp -Foreground Red
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$tmp = $Errormsg.ExitNoLinkReplacement
|
||||||
|
write-host $tmp
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$tmp = @{'msDS-OIDToGroupLink'= $group.DistinguishedName}
|
||||||
|
set-adobject -Identity $OID -Add $tmp
|
||||||
|
if ($?) {
|
||||||
|
$tmp = $Errormsg.LinkSuccess
|
||||||
|
write-host $tmp -Foreground Green
|
||||||
|
}else{
|
||||||
|
$tmp = $ErrorMsg.LinkError
|
||||||
|
write-host $tmp -Foreground Red
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> If you're having trouble running this script, try replacing the single quote after the ConvertFrom-StringData parameter.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Troubleshooting Credential Guard
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Known Issues
|
||||||
|
|
||||||
|
Microsoft is aware of certain issues with Credential Guard that affect client machines that run Windows 10.
|
||||||
|
• For devices with Credential Guard enabled, a sign-in attempt that fails because of a bad password counts as two bad password attempts instead of one. Consequently, if your enterprise has an account lockout policy based on a certain number of failed password attempts, that threshold will be reached in half the number of attempts.
|
||||||
|
|
||||||
|
This issue has been resolved for clients that run Windows 10 version 1703. For clients that run Windows 10 version 1607, a hotfix is available for download to resolve the issue. For clients that run Windows 10 versions 1507 or 1511, no hotfix is available. For those operating systems, to resolve the issue, you can upgrade the client to a later version of Windows 10. As a workaround, administrators can either choose to increase the account lockout threshold accordingly, consistent with current security policy, or can disable Credential Guard. For further information, see Credential Guard generates double bad password count
|
||||||
|
|
||||||
|
Credential guard has known issues on Windows 10 when used with certain third-party applications:
|
||||||
|
|
||||||
|
• Applications Appsense and Lumension E S. are known to cause high CPU utilization on Windows 10 client machines with credential guard enabled.
|
||||||
|
• Citrix Applications are known to cause high CPU utilization on Windows 10 client machines. This issue is currently under investigation.
|
||||||
|
• Cisco Proxy Agents are known to cause authentication failure on Windows 10 client machines. This issue is currently under investigation.
|
||||||
|
• Client machines with Credential Guard enabled cannot access shares on For further information see: Machines with Credential Guard enabled unable to connect to IBM File Servers
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### How-to
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## See also
|
## See also
|
||||||
|
|
||||||
**Deep Dive into Credential Guard: Related videos**
|
**Deep Dive into Credential Guard: Related videos**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user