In the previous post, We worked on to get started with Windows PowerShell. We looked at setting up the PowerShell environment and running a sample Script.
In this post, we will learn and understand an important part while automating things is working with credentials. While many of the cmdlets parameters support credentials.
Most of those cmdlets, whether you work on PowerShell Core or Windows PowerShell, can be executed remotely and with different credentials.
In order to see which cmdlets support a Credential parameter, you can use the ParameterName parameter with Get-Command to discover them.
Get-Command -ParameterName Credential
First of all, we need to see what a credential actually is by looking at the following code :
$username = ‘venkat’ $password = 'P@ssw0rd' | ConvertTo-SecureString -AsPlainText -Force $newCredential = New-Object -TypeName pscredential $userName, $password $newCredential.GetType().FullName $newCredential | Get-Member
Looking at the code, you can see that the pscredential object type is inherently related to PowerShell, coming from the System.Management.Automation namespace. When viewing the members of that type with Get-Member, you can see that you are able to retrieve the password once you have entered it. However, the password is encrypted with the Data Protection API (DPAPI).
To learn more about the DPAPI, please visit https://docs.microsoft.com/en-us/dotnet/standard/security/how-to-use-data-protection.
How it is useful ?
You can now use your credentials for various purposes, for example, to create local users and groups, create services, authenticate with web services, and many more. We will revisit these examples later in this chapter when we look at REST APIs and external commands.
$userName = 'test-domain\test-login' $password = 'test-password' $pwdSecureString = ConvertTo-SecureString -Force -AsPlainText $password $credential = New-Object -TypeName System.Management.Automation.PSCredential ` -ArgumentList $userName, $pwdSecureString
Using the .NET method GetNetworkCredential gives quite a different result. The plaintext password is displayed right beside the encrypted password.
This is by no means a gaping security hole—with the DPAPI, the account on your system already has access to the password. With a few .NET, we can mimic the behavior of the GetNetworkCredential method:
$newCredential.Password # Using GetNetworkCredential, it's plaintext again $newCredential.GetNetworkCredential() | Get-Member $newCredential.GetNetworkCredential().Password
To securely store credentials at rest, the built-in Protect-CmsMessage and Unprotect-CmsMessage cmdlets can be used with PowerShell 5 and later. Cryptographic Message Syntax (CMS) cmdlets leverage certificate-based encryption to store data securely.
To test this we first will create a self-signed certificate and this can be achieved using the below command.
New-SelfSignedCertificate -Subject TestCert -KeyUsage KeyEncipherment -CertStoreLocation Cert:\Venkat\My -Type DocumentEncryptionCert Protect-CmsMessage -to CN=SomeRecipient -Content "Securable goes here" | Out-File .\EncryptedContent.txt
In this post, we saw how to work with credentials which will help us to use while scheduling scripts, calling Rest API, etc. This is one of the core concepts while working with PowerShell. I hope this makes sense in understanding and its usage.