mirror of
https://github.com/MicrosoftDocs/windows-itpro-docs.git
synced 2025-05-27 20:57:23 +00:00
488 lines
19 KiB
Markdown
488 lines
19 KiB
Markdown
---
|
||
title: Scripts for Certificate Issuance Policies in Credential Guard (Windows 10)
|
||
description: Scripts listed in this topic for obtaining the available issuance policies on the certificate authority for Credential Guard on Windows 10.
|
||
ms.prod: w10
|
||
ms.mktglfcycl: explore
|
||
ms.sitesec: library
|
||
ms.pagetype: security
|
||
localizationpriority: high
|
||
author: brianlic-msft
|
||
---
|
||
|
||
# Credential Guard: Scripts for Certificate Authority Issuance Policies
|
||
|
||
|
||
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. |