|
| 1 | +# Credentials Options in Configuration Data |
| 2 | +>Applies To: Windows PowerShell 5.0 |
| 3 | +
|
| 4 | +## Plain Text Passwords and Domain Users |
| 5 | + |
| 6 | +DSC configurations containing a credential without encryption will generate an error messages about plain text passwords. |
| 7 | +Also, DSC will generate a warning when using domain credentials. |
| 8 | +These error and warning messages can be silenced using the DSC configuration data keywords: |
| 9 | +* **PsDscAllowPlainTextPassword** |
| 10 | +* **PsDscAllowDomainUser** |
| 11 | + |
| 12 | +## Handling Credentials in DSC |
| 13 | + |
| 14 | +DSC configuration resources run as `Local System` by default. |
| 15 | +However, some resources require a credential, like when the `Package` resource needs to install software under a specific user account. |
| 16 | + |
| 17 | +Earlier resources used a hard-coded `Credential` property name to handle this. |
| 18 | +WMF 5.0 added an automatic `PsDscRunAsCredential` property for all resources. |
| 19 | +Newer resources and custom resources can use this automatic property instead of creating their own property for credentials. |
| 20 | + |
| 21 | +*Note that some resources are designed to use multiple credentials for a specific reason, and they will have their own credential properties.* |
| 22 | + |
| 23 | +To identify the available credential properties on a resource use either `Get-DscResource -Name ResourceName -Syntax` or the Intellisense in the ISE (`CTRL+SPACE`). |
| 24 | + |
| 25 | +```PowerShell |
| 26 | +PS C:\> Get-DscResource -Name Group -Syntax |
| 27 | +Group [String] #ResourceName |
| 28 | +{ |
| 29 | + GroupName = [string] |
| 30 | + [Credential = [PSCredential]] |
| 31 | + [DependsOn = [string[]]] |
| 32 | + [Description = [string]] |
| 33 | + [Ensure = [string]{ Absent | Present }] |
| 34 | + [Members = [string[]]] |
| 35 | + [MembersToExclude = [string[]]] |
| 36 | + [MembersToInclude = [string[]]] |
| 37 | + [PsDscRunAsCredential = [PSCredential]] |
| 38 | +} |
| 39 | +``` |
| 40 | + |
| 41 | +This example uses a [Group](https://msdn.microsoft.com/en-us/powershell/dsc/groupresource) resource from the `PSDesiredStateConfiguration` built-in DSC resource module. |
| 42 | +It can create local groups and add or remove members. |
| 43 | +It accepts both the `Credential` property and the automatic `PsDscRunAsCredential` property. |
| 44 | +However, it is coded to only use the `Credential` property. |
| 45 | +Read more about `PsDscRunAsCredential` in the [WMF Release Notes](https://msdn.microsoft.com/en-us/powershell/wmf/dsc_runas). |
| 46 | + |
| 47 | +## Example: The Group resource Credential property |
| 48 | + |
| 49 | +DSC runs under `Local System`, so it already has permissions to modify local users and groups. |
| 50 | +If the member to be added is a local account, then no credential is required. |
| 51 | +If the `Group` resource adds a domain account to the local group, then a credential is required. |
| 52 | + |
| 53 | +Anonymous queries to Active Directory are not allowed. |
| 54 | +The `Credential` property of the `Group` resource is the domain account used to query Active Directory. |
| 55 | +For most purposes this can be a generic user account, because by default users can *read* most of the objects in Active Directory. |
| 56 | + |
| 57 | +## Example Configuration |
| 58 | + |
| 59 | +The following example code uses DSC to populate a local group with a domain user: |
| 60 | + |
| 61 | +```PowerShell |
| 62 | +Configuration DomainCredentialExample |
| 63 | +{ |
| 64 | +param( |
| 65 | + [PSCredential]$DomainCredential |
| 66 | +) |
| 67 | + Import-DscResource -ModuleName PSDesiredStateConfiguration |
| 68 | +
|
| 69 | + node localhost |
| 70 | + { |
| 71 | + Group DomainUserToLocalGroup |
| 72 | + { |
| 73 | + GroupName = 'ApplicationAdmins' |
| 74 | + MembersToInclude = 'contoso\alice' |
| 75 | + Credential = $DomainCredential |
| 76 | + } |
| 77 | + } |
| 78 | +} |
| 79 | +
|
| 80 | +$cred = Get-Credential -UserName contoso\genericuser -Message "Password please" |
| 81 | +DomainCredentialExample -DomainCredential $cred |
| 82 | +``` |
| 83 | + |
| 84 | +This code generates both an error and warning message: |
| 85 | + |
| 86 | +``` |
| 87 | +ConvertTo-MOFInstance : System.InvalidOperationException error processing |
| 88 | +property 'Credential' OF TYPE 'Group': Converting and storing encrypted |
| 89 | +passwords as plain text is not recommended. For more information on securing |
| 90 | +credentials in MOF file, please refer to MSDN blog: |
| 91 | +http://go.microsoft.com/fwlink/?LinkId=393729 |
| 92 | +
|
| 93 | +At line:11 char:9 |
| 94 | ++ Group |
| 95 | +At line:297 char:16 |
| 96 | ++ $aliasId = ConvertTo-MOFInstance $keywordName $canonicalizedValue |
| 97 | ++ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 98 | + + CategoryInfo : InvalidOperation: (:) [Write-Error], InvalidOperationException |
| 99 | + + FullyQualifiedErrorId : FailToProcessProperty,ConvertTo-MOFInstance |
| 100 | +
|
| 101 | +WARNING: It is not recommended to use domain credential for node 'localhost'. |
| 102 | +In order to suppress the warning, you can add a property named |
| 103 | +'PSDscAllowDomainUser' with a value of $true to your DSC configuration data |
| 104 | +for node 'localhost'. |
| 105 | +``` |
| 106 | + |
| 107 | +This example has two issues: |
| 108 | +1. An error explains that plain text passwords are not recommended |
| 109 | +2. A warning advises against using a domain credential |
| 110 | + |
| 111 | +## PsDscAllowPlainTextPassword |
| 112 | + |
| 113 | +The first error message has a URL with documentation. |
| 114 | +This link explains how to encrypt passwords using a [ConfigurationData](https://msdn.microsoft.com/en-us/powershell/dsc/configdata) structure and a certificate. |
| 115 | +For more information on certificates and DSC [read this post](http://aka.ms/certs4dsc). |
| 116 | + |
| 117 | +To force a plain text password, the `PsDscAllowPlainTextPassword` keyword is required in the configuration data section as follows: |
| 118 | + |
| 119 | +```PowerShell |
| 120 | +Configuration DomainCredentialExample |
| 121 | +{ |
| 122 | +param( |
| 123 | + [PSCredential]$DomainCredential |
| 124 | +) |
| 125 | + Import-DscResource -ModuleName PSDesiredStateConfiguration |
| 126 | +
|
| 127 | + node localhost |
| 128 | + { |
| 129 | + Group DomainUserToLocalGroup |
| 130 | + { |
| 131 | + GroupName = 'ApplicationAdmins' |
| 132 | + MembersToInclude = 'contoso\alice' |
| 133 | + Credential = $DomainCredential |
| 134 | + } |
| 135 | + } |
| 136 | +} |
| 137 | +
|
| 138 | +$cd = @{ |
| 139 | + AllNodes = @( |
| 140 | + @{ |
| 141 | + NodeName = 'localhost' |
| 142 | + PSDscAllowPlainTextPassword = $true |
| 143 | + } |
| 144 | + ) |
| 145 | +} |
| 146 | +
|
| 147 | +$cred = Get-Credential -UserName contoso\genericuser -Message "Password please" |
| 148 | +DomainCredentialExample -DomainCredential $cred -ConfigurationData $cd |
| 149 | +``` |
| 150 | + |
| 151 | +*Note that `NodeName` cannot equal asterisk. It must be a specific node name.* |
| 152 | + |
| 153 | +**Microsoft advises to avoid plain text passwords due to the significant security risk.** |
| 154 | + |
| 155 | +## Domain Credentials |
| 156 | + |
| 157 | +Running the example configuration script again (with or without encryption), still generates the warning that using a domain account for a credential is not recommended. |
| 158 | +Using a local account eliminates potential exposure of domain credentials that can be used on other servers. |
| 159 | + |
| 160 | +**When using credentials with DSC resources, prefer a local account over a domain account when possible.** |
| 161 | + |
| 162 | +If there is a '\' or '@' in the `Username` property of the credential, then DSC will treat it as a domain account. |
| 163 | +An exception is made for "localhost", "127.0.0.1", and "::1" in the domain portion of the user name. |
| 164 | + |
| 165 | +## PSDscAllowDomainUser |
| 166 | + |
| 167 | +In the DSC `Group` resource example above, querying an Active Directory domain *requires* the use of a domain account. |
| 168 | +In this case add the `PSDscAllowDomainUser` property to the `ConfigurationData` block as follows: |
| 169 | + |
| 170 | +```PowerShell |
| 171 | +$cd = @{ |
| 172 | + AllNodes = @( |
| 173 | + @{ |
| 174 | + NodeName = 'localhost' |
| 175 | + PSDscAllowDomainUser = $true |
| 176 | + # PSDscAllowPlainTextPassword = $true |
| 177 | + CertificateFile = "C:\PublicKeys\server1.cer" |
| 178 | + } |
| 179 | + ) |
| 180 | +} |
| 181 | +``` |
| 182 | + |
| 183 | +Now the configuration script will generate the MOF file with no errors or warnings. |
0 commit comments