Powershell add credentials to credential manager

Powershell add credentials to credential manager DEFAULT

Add Credential support to PowerShell functions

  • 8 minutes to read

Note

The original version of this article appeared on the blog written by @joshduffney. This article has been edited for inclusion on this site. The PowerShell team thanks Josh for sharing this content with us. Please check out his blog at duffney.io.

This article shows you how to add credential parameters to PowerShell functions and why you'd want to. A credential parameter is to allow you to run the function or cmdlet as a different user. The most common use is to run the function or cmdlet as an elevated user account.

For example, the cmdlet has a Credential parameter, which you could provide domain admin credentials to create an account in a domain. Assuming your normal account running the PowerShell session doesn't have that access already.

Creating credential object

The PSCredential object represents a set of security credentials such as a user name and password. The object can be passed as a parameter to a function that runs as the user account in that credential object. There are a few ways that you can create a credential object. The first way to create a credential object is to use the PowerShell cmdlet . When you run without parameters, it prompts you for a username and password. Or you can call the cmdlet with some optional parameters.

To specify the domain name and username ahead of time you can use either the Credential or UserName parameters. When you use the UserName parameter, you're also required to provide a Message value. The code below demonstrates using the cmdlet. You can also store the credential object in a variable so that you can use the credential multiple times. In the example below, the credential object is stored in the variable .

Sometimes, you can't use the interactive method of creating credential objects shown in the previous example. Most automation tools require a non-interactive method. To create a credential without user interaction, create a secure string containing the password. Then pass the secure string and user name to the method.

Use the following command to create a secure string containing the password:

Both the AsPlainText and Force parameters are required. Without those parameters, you receive a message warning that you shouldn't pass plain text into a secure string. PowerShell returns this warning because the plain text password gets recorded in various logs. Once you have a secure string created, you need to pass it to the method to create the credential object. In the following example, the variable contains the secure string contains the credential object.

Now that you know how to create credential objects, you can add credential parameters to your PowerShell functions.

Adding a Credential Parameter

Just like any other parameter, you start off by adding it in the block of your function. It's recommended that you name the parameter because that's what existing PowerShell cmdlets use. The type of the parameter should be .

The following example shows the parameter block for a function called . It has two parameters: and .

The code in this example is enough to have a working credential parameter, however there are a few things you can add to make it more robust.

  • Add the validation attribute to check that the value being passed to Credential. If the parameter value is null, this attribute prevents the function from executing with invalid credentials.

  • Add . This allows you to pass in a username as a string and have an interactive prompt for the password.

  • Set a default value for the parameter to . Your function you might be passing this object to existing PowerShell cmdlets. Providing a null value to the cmdlet called inside your function causes an error. Providing an empty credential object avoids this error.

Tip

Some cmdlets that accept a credential parameter do not support as they should. See the Dealing with Legacy Cmdlets section for a workaround.

Using credential parameters

The following example demonstrates how to use credential parameters. This example shows a function called , which is out of The Pester Book. This function defines the credential parameter using the techniques describe in the previous section. The function calls using the variable created by the function. This allows you to change the user who's running . Because the default value of is an empty credential, the function can run without providing credentials.

The following sections show different methods of providing credentials to .

Prompting for credentials

Using in parentheses at run time causes the to run first. You are prompted for a username and password. You could use the Credential or UserName parameters of to pre-populate the username and domain. The following example uses a technique called splatting to pass parameters to the function. For more information about splatting, check out the about_Splatting article.

Get a credential at runtime

Using seems cumbersome. Normally, when you use the Credential parameter with only a username, the cmdlet automatically prompts for the password. The attribute enables this behavior.

Prompt for credentials

Note

To set the registry value shown, these examples assume you have the Web Server features of Windows installed. Run and if required.

Provide credentials in a variable

You can also populate a credential variable ahead of time and pass it to the Credential parameter of function. Use this method with Continuous Integration / Continuous Deployment (CI/CD) tools such as Jenkins, TeamCity, and Octopus Deploy. For an example using Jenkins, check out Hodge's blog post Automating with Jenkins and PowerShell on Windows - Part 2.

This example uses the .NET method to create the credential object and a secure string to pass in the password.

For this example, the secure string is created using a clear text password. All of the previously mentioned CI/CD have a secure method of providing that password at run time. When using those tools, replace the plain text password with the variable defined within the CI/CD tool you use.

Run without credentials

Since defaults to an empty credential object, you can run the command without credentials, as shown in this example:

Dealing with legacy cmdlets

Not all cmdlets support credential objects or allow empty credentials. Instead, the cmdlet wants username and password parameters as strings. There are a few ways to work around this limitation.

Using if-else to handle empty credentials

In this scenario, the cmdlet you want to run doesn't accept an empty credential object. This example adds the Credential parameter to only if it's not empty. Otherwise, it runs the without the Credential parameter.

Using splatting to handle empty credentials

This example uses parameter splatting to call the legacy cmdlet. The object is conditionally added to the hash table for splatting and avoids the need to repeat the script block. To learn more about splatting inside functions, see the Splatting Parameters Inside Advanced Functions blog post.

Working with string passwords

The cmdlet is an example of a cmdlet that accepts a string as a password. allows you to run simple SQL insert, update, and delete statements. requires a clear-text username and password rather than a more secure credential object. This example shows how to extract the username and password from a credential object.

The function in this example calls the cmdlet to query a SQL server for all its databases. The function defines a Credential parameter with the same attribute used in the previous examples. Since the username and password exist within the variable, you can extract those values for use with .

The user name is available from the UserName property of the variable. To obtain the password, you have to use the method of the object. The values are extracted into variables that are added to a hash table used for splatting parameters to .

Continued learning credential management

Creating and storing credential objects securely can be difficult. The following resources can help you maintain PowerShell credentials.

Sours: https://docs.microsoft.com/en-us/powershell/scripting/learn/deep-dives/add-credentials-to-powershell-functions

Add Credentials To PowerShell Functions

In this blog post, I’ll show you how to add credential parameters to PowerShell functions. But before I do that let’s first talk about why you’d want to add a credential parameter to your functions. The purpose of the credential parameter is to allow you to run the function and/or cmdlet as a different user, some account other than the one currently running the PowerShell session. The most common use is to run the function or cmdlet as an elevated user account.

For example, the cmdlet has a parameter, which you could provide domain admin credentials in order to create an account in a domain. Assuming your normal account running the PowerShell session doesn’t have that access already.

This blog post walks you through the process of adding such functionality to your PowerShell functions. I also discuss how to get around common issues when working with legacy cmdlets that don’t support a credential object, but before we get started let’s first talk about PSCredential objects and how to generate them.

Creating Credential Object

PSCredential objects represent a set of security credentials, such as a user name and password.MSDN The objects are then passed to the parameter of a function and used to execute the function as that user account in the credential object. There are a few ways that you can generate a credential object. The first and easiest method is by using the PowerShell cmdlet . You can simply execute , which will result in a username and password prompt. From there you could enter the domainName\userName or you can call the cmdlet with some optional parameters.

To specify the domain name and username ahead of time you can use either the or parameters. The only difference I’ve noticed is when you use you’ll also be required to input a message value. The code below demonstrates using the cmdlet. You can also store the credential object in a variable, which allows you to use the credential several times. In the example below, I’m storing each credential object to a variable called $Cred.

Sometimes, you won’t want an interactive method of creating credential objects as I just demonstrated. Most automation tools such as Jenkins, TeamCity, and Octopus Deploy require a non-interactive method. To do this you’ll have to create a secure string, which contains the password. You then have to pass the secure string and user name to the ’s PSCredential method. Sounds a lot more complicated than it is, I assure you.

The syntax for creating a secure string looks like this . Both the and parameters are required or you’ll receive error messages saying you shouldn’t pass plain text into a secure string.

The reason being, if your PowerShell session is logged, that password would exist in the log. With the secure string created you’ll need to pass it to the PSCredential method to create the credential object. That syntax looks like this . In the example below, I’m storing the secure string into a variable called $password and the credential object into a variable $Cred.

Now that you know how to create credential objects, it’s now time to talk about how we add credential parameters to our PowerShell functions.

Adding a Credential Parameter

Just like any other parameter, you start off by adding it in the param block of your function. I typically use the parameter name of $Credential because that’s what existing PowerShell cmdlets use.

With the parameter added, you then have to define its type, which you just learned is . Before we move on, take a moment to look at the code snippet below. It is for a function called Get-Something. It has two parameters, $Name and $Credential, which has the type.

The code above would be enough to have a working credential parameter, however there are a few things you can add to make it more robust.

The first thing you can add is , which checks to see if the value being passed to is null. If it is, it will stop the function from executing. If you don’t have proper credential input specified, why execute?

The next thing you can add is . This allows you to pass in a username as a string and have an interactive prompt for the password, which I’ll demonstrate later in the post.

Lastly, you can do is set a default value for the $Credential parameter. Adding as a default value will populate an empty credential object. Why do this? Well, in your code you might be passing this $Credential object to existing PowerShell cmdlets that use the parameter. If you do not provide a credential object to your function, the code will error out when it hits the cmdlet inside your code that requires a credential. By providing a default empty credential object, you can resolve that error.

There are a few other methods for handling this problem. One is a simple if statement and another option are to use splatting. I’ll walk through this later in the post. The snippet of code below shows what the function would now look like with all these changes.

TIP: - Some cmdlets that accept a credential parameter do not support as they should. See the Dealing with Legacy Cmdlets section for a workaround.

Using Credential Parameters

In this next section of the post, I’m going to demonstrate how to use credential parameters. I’ll be using a function called , which is out of The Pester Book. I’ve added the credential parameter by using the techniques you just learned above. Inside the function, it uses Invoke-Command. I’ve updated it to use the parameter and then added the $Credential variable created by the function. This allows me to change the user who’s running Invoke-Command.

Because I’ve included as the default value, it should work with no credentials being passed and with credentials being passed. So, let’s test it out and see if it works as we expect. The code is below if you’d like to follow along.

With Credentials

The first way I can use the -Credential parameter of is by using in at run time. This will cause the to run first just like a math problem. You’ll then be prompted for a username and password. You could use the or parameters of to pre-populate the username and domain. If you’re not familiar with a technique called splatting, that’s how I’m passing the rest of the parameters to the function. For more information about splatting, check out this MSDN article

GetCredAtRunTime

Having to use seems a little weird, doesn’t it?

Normally, when you run cmdlets that support the parameter you can just put in your username and it will automatically prompted for the password.

Well, because we used in the function, we can do that! Just remember to put the username as a string right after the parameter and you’ll get prompted for your password.

GetCredsPrompt

TIP: - If you’re following allong you’ll need to install a few windows features to create this registry value. Run and if required.

With Credentials in a variable

You can also populate a credential variable ahead of time and pass it to the parameter of function. I use the following method a lot when working with continuous integration and continuous deployment tools such as Jenkins, TeamCity, and Octopus Deploy.

I use the .Net method to create the credential object as well as use a secure string to pass in the password. You’ll notice the password is in clear text when I create the secure string. All of the CI and CD tools I just mentioned have a secure method of populating that at run time so when using those tools, I replace the plain text password with a variable defined within the tool I’m using.

For an example of that, check out Hodge’s blog post Automating with Jenkins and PowerShell on Windows - Part 2.

Without Credentials

Since I added as the default value of the parameter, I can run the command without credentials as well. Remember, that not all cmdlets that have the parameter allow for this. Not to worry though, we can get around this limitation and I’ll discuss how in the next section of the post.

Dealing with Legacy Cmdlets

Being in the tech industry, you’ll never escape the need to support and/or deal with legacy applications. Working in PowerShell is no different and in this case, you’ll eventually run into one or both of the following problems.

A cmdlet doesn’t support , which I’ve mentioned a few times. Or, the cmdlet you want to use doesn’t even support the parameter at all and instead accepts a string username and string password! This section of the blog post is dedicated to helping you solve this problem. First, up is, what to do when a cmdlet doesn’t support .

Using If Else to Handle Empty Credentials

Before I dive into solving this problem, let me first expand on what the problem is. So, what does it mean when I say the cmdlet doesn’t support ?

It means that when you do not provide a credential object, the function you wrote will fail because the cmdlet inside your function will fail as it’s unable to accept the empty credential object. The function you wrote will work wonderfully as long as you supply a credential object, but as soon as you don’t, no dice. So, how do we fix it?

There are a few ways, the first is to check the parameter for a value with an if-else statement. The if statement checks the value of the $credential and adds the parameter to only if it’s not empty, otherwise it issues the without the parameter.

Using Splatting to Handle Empty Credentials

Another way to address this problem is to use splatting. I still use an if statement to determine if $credential is empty or not, but the difference is I’m just adding a $credential object to a hash table, instead of repeating the entire block of code that uses .

To learn more about splatting inside functions, check out a previous blog post of mine Splatting Parameters Inside Advanced Functions. That wraps up dealing with cmdlets that don’t support , so let’s move on to dealing with cmdlets that don’t even have a parameter.

Working with [string] Passwords

A good example of a cmdlet that accepts a string as a password is the cmdlet. Invoke-Sqlcmd is an extremely useful cmdlet that allows you to interact with SQL via PowerShell. I use it all the time within my code to perform simple SQL insert, update, and delete statements. The problem is, I don’t want to pass a clear text password to my function in order to use Invoke-Sqlcmd. I want to pass a credential object like I would when using a modern and well-designed PowerShell cmdlet.

To accomplish this I have to hydrate and dehydrate a credential object. Which is fancy talk for create a credential object and extract out the username and password from it. You’ve already learned how to create credential objects in this blog post so I won’t cover that in much detail. However, I will step the process of extracting or dehydrating the username and password from a credential object.

To demonstrate how to dehydrate a credential object, I’ve written a PowerShell function called . This function wraps around the cmdlet and queries a SQL server for all its databases. Notice that I have all the settings used before to add a credential parameter to my function. This allows me to pass in a credential object like I’ve been teaching you throughout this post. But, how is that going to work if doesn’t support the object?

Well, the username and password exist within the variable. So, all we have to do is extract it. The user name is easy to obtain, we can get that by calling out the UserName property of the $Credential variable. In the example below, I’m storing that into a variable called $UserName. To obtain the password you have to use the method of the $Credential object. The syntax for that is . I’m taking the output of that, which is the password as a string and storing it to a variable called $Password. Keep in mind these variables are only accessible inside the function.

Now, that I have a username and password variable stored as a string I can pass those to the . Instead of passing all the parameters and values on a single line, I chose to create a hash table and splat them to the cmdlet. I didn’t need to create an extra $UserName and $Password variable in this example. I could of just put the code inside the hash table or directly to the parameters, but this makes it a little easier to see what’s going on.

Continued Learning Credential Management

Creating and storing credential objects can be a pain, to help maintain your PowerShell credentials I recommend checking out the following PowerShell module and blog post.

BetterCredentials

Using Credentials in your Profile

Other solutions

Azure Key Vault

Vault Project

Sources

PowerShell.Org: using-credential-param-as-optional

powershell-how-to-create-a-pscredential-object

Shout Out

I want to give a shout out to Joel Bennett. He was kind enough to review this blog post and provide some really great technical insights. With his help, I learned as much as you did, if not more. Teaching is the best way to learn after all. Thanks, Joel!

Sours: https://duffney.io/addcredentialstopowershellfunctions/
  1. Cancel showtime on xfinity
  2. Ashley olsen hair color
  3. Ryobi hand saw battery

I have been having trouble for a while dealing with credentials and how to store them when using them in scripts. I have done the whole just do Get-Credential and enter it every time I run the script but that is a great for one off scripts but not for scheduled tasks. In the past i had just been using the Import-Clixml and importing the creds saved from a txt file. This works well but now you have to deal with actual txt files. I ran across a article somewhere reading on something else and remember someone saying something about saving credentials to the Windows Credential manager. After doing some research and some digging and reading found this Gem of a Powershell module. CredentialManager Module is a easy module to use, and simplistic with only 4 commands.

Get-StoredCredential
Get-StrongPassword
New-StoredCredential
Remove-StoredCredential

With these 4 commands you can now save credentials and call credentials from the credential manager. This is a huge win for me. No more having to deal with cred files, trying to remember what account created the txt file and fighting that mess.

Creating Stored Credentials

New-StoredCredential -Comment 'Test_Creds' -Credentials $(Get-Credential) -Target 'TestCreds'

Using the stored Credentials

Get-StoredCredential -Target 'TestCreds'

This will show the below but that does not help you.

If you store this into a variable now you can use this variable for your credentials as you normally would.

$TestCreds = Get-StoredCredential -Target 'TestCreds'

Removing Stored Credentials

Cleaning up old credentials is always great housekeeping.

Remove-StoredCredential -Target 'TestCreds'

Using Strong Passwords

Get-StrongPassword -Length 20 -NumberOfSpecialCharacters 4

The command will get you the a password that is 20 characters long with 4 special characters. This is a quick way to generate a password for the needs.

With this little bit of info has saved me a huge amount of time. I am not claiming that Credential manager the most secure method, but its way better than saving the passwords in clear text in the script. And much more manageable than having to deal with txt files.

Like this:

LikeLoading...

About childebrandt42

I am a jack of all trades and a master of a few things. Manage a enterprise VDI deployment for a living. Automate things, work on my media server and fish for hobbies. Monkey tamer at home!

View all posts by childebrandt42 →

This entry was posted in CLI and Powershell, DevOps, Random Crap, Security and tagged Credentials, Credentials Manager, Creds, Powershell. Bookmark the permalink.

Sours: https://childebrandt42.wordpress.com/2020/07/07/using-windows-credential-manager-with-powershell/

This script will add a list of credentials to the Windows Credential Manager and then map some drives.  It will also then change your default documents location to a network UNC path.

To use just change your network locations in the drive mapping section at the end and update the usernames and passwords.

function add-creds { <# .Synopsis Provides access to Windows CredMan basic functionality for client scripts ****************** IMPORTANT ****************** * * If you use this script from the PS console, you * should ALWAYS pass the Target, User and Password * parameters using single quotes: * * add-creds -AddCred -Target 'http://server' -User 'JoeSchmuckatelli' -Pass '[email protected]!' * * to prevent PS misinterpreting special characters * you might use as PS reserved characters * ****************** IMPORTANT ****************** .Description Provides the following API when dot-sourced Del-Cred Enum-Creds Read-Cred Write-Cred Supports the following cmd-line actions AddCred (requires -User, -Pass; -Target is optional) DelCred (requires -Target) GetCred (requires -Target) RunTests (no cmd-line opts) ShoCred (optional -All parameter to dump cred objects to console) .INPUTS See function-level notes .OUTPUTS Cmd-line usage: console output relative to success or failure state Dot-sourced usage: ** Successful Action ** * Del-Cred : Int = 0 * Enum-Cred : PsUtils.CredMan+Credential[] * Read-Cred : PsUtils.CredMan+Credential * Write-Cred : Int = 0 ** Failure ** * All API : Management.Automation.ErrorRecord .NOTES Author: Jim Harrison ([email protected]) Date : 2012/05/20 Vers : 1.5 Updates: 2012/10/13 - Fixed a bug where the script would only read, write or delete GENERIC credentials types. - Added #region blocks to clarify internal functionality - Added 'CredType' param to specify what sort of credential is to be read, created or deleted (not used for -ShoCred or Enum-Creds) - Added 'CredPersist' param to specify how the credential is to be stored; only used in Write-Cred - Added 'All' param for -ShoCreds to differentiate between creds summary list and detailed creds dump - Added CRED_FLAGS enum to make the credential struct flags values clearer - Improved parameter validation - Expanded internal help (used with Get-Help cmdlet) - Cmd-line functions better illustrate how to interpret the results when dot-sourcing the script .PARAMETER AddCred Specifies that you wish to add a new credential or update an existing credentials -Target, -User and -Pass parameters are required for this action .PARAMETER Comment Specifies the information you wish to place in the credentials comment field .PARAMETER CredPersist Specifies the credentials storage persistence you wish to use Valid values are: "SESSION", "LOCAL_MACHINE", "ENTERPRISE" NOTE: if not specified, defaults to "ENTERPRISE" .PARAMETER CredType Specifies the type of credential object you want to store Valid values are: "GENERIC", "DOMAIN_PASSWORD", "DOMAIN_CERTIFICATE", "DOMAIN_VISIBLE_PASSWORD", "GENERIC_CERTIFICATE", "DOMAIN_EXTENDED", "MAXIMUM", "MAXIMUM_EX" NOTE: if not specified, defaults to "GENERIC" ****************** IMPORTANT ****************** * * I STRONGLY recommend that you become familiar * with http://msdn.microsoft.com/en-us/library/windows/desktop/aa374788(v=vs.85).aspx * before you create new credentials with -CredType other than "GENERIC" * ****************** IMPORTANT ****************** .PARAMETER DelCred Specifies that you wish to remove an existing credential -CredType may be required to remove the correct credential if more than one is specified for a target .PARAMETER GetCred Specifies that you wish to retrieve an existing credential -CredType may be required to access the correct credential if more than one is specified for a target .PARAMETER Pass Specifies the credentials password .PARAMETER RunTests Specifies that you wish to run built-in Win32 CredMan functionality tests .PARAMETER ShoCred Specifies that you wish to retrieve all credential stored for the interactive user -All parameter may be used to indicate that you wish to view all credentials properties (default display is a summary list) .PARAMETER Target Specifies the authentication target for the specified credentials If not specified, the -User information is used .PARAMETER User Specifies the credentials username .LINK http://msdn.microsoft.com/en-us/library/windows/desktop/aa374788(v=vs.85).aspx http://stackoverflow.com/questions/7162604/get-cached-credentials-in-powershell-from-windows-7-credential-manager http://msdn.microsoft.com/en-us/library/windows/desktop/aa374788(v=vs.85).aspx http://blogs.msdn.com/b/peerchan/archive/2005/11/01/487834.aspx .EXAMPLE add-creds -AddCred -Target 'http://aserver' -User 'UserName' -Password '[email protected]!' -Comment 'cuziwanna' Stores the credential for 'UserName' with a password of '[email protected]!' for authentication against 'http://aserver' and adds a comment of 'cuziwanna' .EXAMPLE add-creds -DelCred -Target 'http://aserver' -CredType 'DOMAIN_PASSWORD' Removes the credential used for the target 'http://aserver' as credentials type 'DOMAIN_PASSWORD' .EXAMPLE add-creds -GetCred -Target 'http://aserver' Retreives the credential used for the target 'http://aserver' .EXAMPLE add-creds -ShoCred Retrieves a summary list of all credentials stored for the interactive user .EXAMPLE add-creds -ShoCred -All Retrieves a detailed list of all credentials stored for the interactive user #> #requires -version 2 Param ( [Parameter(Mandatory=$false)][Switch] $AddCred, [Parameter(Mandatory=$false)][Switch] $DelCred, [Parameter(Mandatory=$false)][Switch] $GetCred, [Parameter(Mandatory=$false)][Switch] $ShoCred, [Parameter(Mandatory=$false)][Switch] $RunTests, [Parameter(Mandatory=$false)][ValidateLength(1,32767) <# CRED_MAX_GENERIC_TARGET_NAME_LENGTH #>][String] $Target, [Parameter(Mandatory=$false)][ValidateLength(1,512) <# CRED_MAX_USERNAME_LENGTH #>][String] $User, [Parameter(Mandatory=$false)][ValidateLength(1,512) <# CRED_MAX_CREDENTIAL_BLOB_SIZE #>][String] $Pass, [Parameter(Mandatory=$false)][ValidateLength(1,256) <# CRED_MAX_STRING_LENGTH #>][String] $Comment, [Parameter(Mandatory=$false)][Switch] $All, [Parameter(Mandatory=$false)][ValidateSet("GENERIC", "DOMAIN_PASSWORD", "DOMAIN_CERTIFICATE", "DOMAIN_VISIBLE_PASSWORD", "GENERIC_CERTIFICATE", "DOMAIN_EXTENDED", "MAXIMUM", "MAXIMUM_EX")][String] $CredType = "GENERIC", [Parameter(Mandatory=$false)][ValidateSet("SESSION", "LOCAL_MACHINE", "ENTERPRISE")][String] $CredPersist = "ENTERPRISE" ) #region Pinvoke #region Inline C# [String] $PsCredmanUtils = @" using System; using System.Runtime.InteropServices; namespace PsUtils { public class CredMan { #region Imports // DllImport derives from System.Runtime.InteropServices [DllImport("Advapi32.dll", SetLastError = true, EntryPoint = "CredDeleteW", CharSet = CharSet.Unicode)] private static extern bool CredDeleteW([In] string target, [In] CRED_TYPE type, [In] int reservedFlag); [DllImport("Advapi32.dll", SetLastError = true, EntryPoint = "CredEnumerateW", CharSet = CharSet.Unicode)] private static extern bool CredEnumerateW([In] string Filter, [In] int Flags, out int Count, out IntPtr CredentialPtr); [DllImport("Advapi32.dll", SetLastError = true, EntryPoint = "CredFree")] private static extern void CredFree([In] IntPtr cred); [DllImport("Advapi32.dll", SetLastError = true, EntryPoint = "CredReadW", CharSet = CharSet.Unicode)] private static extern bool CredReadW([In] string target, [In] CRED_TYPE type, [In] int reservedFlag, out IntPtr CredentialPtr); [DllImport("Advapi32.dll", SetLastError = true, EntryPoint = "CredWriteW", CharSet = CharSet.Sequential, CharSet = CharSet.Unicode)] public struct Credential { public CRED_FLAGS Flags; public CRED_TYPE Type; public string TargetName; public string Comment; public DateTime LastWritten; public UInt32 CredentialBlobSize; public string CredentialBlob; public CRED_PERSIST Persist; public UInt32 AttributeCount; public IntPtr Attributes; public string TargetAlias; public string UserName; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] private struct NativeCredential { public CRED_FLAGS Flags; public CRED_TYPE Type; public IntPtr TargetName; public IntPtr Comment; public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten; public UInt32 CredentialBlobSize; public IntPtr CredentialBlob; public UInt32 Persist; public UInt32 AttributeCount; public IntPtr Attributes; public IntPtr TargetAlias; public IntPtr UserName; } #endregion #region Child Class private class CriticalCredentialHandle : Microsoft.Win32.SafeHandles.CriticalHandleZeroOrMinusOneIsInvalid { public CriticalCredentialHandle(IntPtr preexistingHandle) { SetHandle(preexistingHandle); } private Credential XlateNativeCred(IntPtr pCred) { NativeCredential ncred = (NativeCredential)Marshal.PtrToStructure(pCred, typeof(NativeCredential)); Credential cred = new Credential(); cred.Type = ncred.Type; cred.Flags = ncred.Flags; cred.Persist = (CRED_PERSIST)ncred.Persist; long LastWritten = ncred.LastWritten.dwHighDateTime; LastWritten = (LastWritten << 32)+ncred.LastWritten.dwLowDateTime;cred.LastWritten =DateTime.FromFileTime(LastWritten);cred.UserName =Marshal.PtrToStringUni(ncred.UserName);cred.TargetName =Marshal.PtrToStringUni(ncred.TargetName);cred.TargetAlias =Marshal.PtrToStringUni(ncred.TargetAlias);cred.Comment =Marshal.PtrToStringUni(ncred.Comment);cred.CredentialBlobSize =ncred.CredentialBlobSize;if(0<ncred.CredentialBlobSize){cred.CredentialBlob =Marshal.PtrToStringUni(ncred.CredentialBlob,(int)ncred.CredentialBlobSize/2);}returncred;}publicCredentialGetCredential(){if(IsInvalid){thrownewInvalidOperationException("InvalidCriticalHandle!");}Credentialcred =XlateNativeCred(handle);returncred;}publicCredential[]GetCredentials(intcount){if(IsInvalid){thrownewInvalidOperationException("InvalidCriticalHandle!");}Credential[]Credentials =newCredential[count];IntPtrpTemp =IntPtr.Zero;for(intinx =0;inx<count;inx++){pTemp =Marshal.ReadIntPtr(handle,inx*IntPtr.Size);Credentialcred =XlateNativeCred(pTemp);Credentials[inx]=cred;}returnCredentials;}overrideprotectedboolReleaseHandle(){if(IsInvalid){returnfalse;}CredFree(handle);SetHandleAsInvalid();returntrue;}}#endregion#regionCustomAPIpublicstaticintCredDelete(stringtarget,CRED_TYPEtype){if(!CredDeleteW(target,type,0)){returnMarshal.GetHRForLastWin32Error();}return0;}publicstaticintCredEnum(stringFilter,outCredential[]Credentials){intcount =0;intFlags =0x0;if(string.IsNullOrEmpty(Filter)||"*"==Filter){Filter =null;if(6<=Environment.OSVersion.Version.Major){Flags =0x1;//CRED_ENUMERATE_ALL_CREDENTIALS;onlyvalidisOS>= Vista } } IntPtr pCredentials = IntPtr.Zero; if (!CredEnumerateW(Filter, Flags, out count, out pCredentials)) { Credentials = null; return Marshal.GetHRForLastWin32Error(); } CriticalCredentialHandle CredHandle = new CriticalCredentialHandle(pCredentials); Credentials = CredHandle.GetCredentials(count); return 0; } public static int CredRead(string target, CRED_TYPE type, out Credential Credential) { IntPtr pCredential = IntPtr.Zero; Credential = new Credential(); if (!CredReadW(target, type, 0, out pCredential)) { return Marshal.GetHRForLastWin32Error(); } CriticalCredentialHandle CredHandle = new CriticalCredentialHandle(pCredential); Credential = CredHandle.GetCredential(); return 0; } public static int CredWrite(Credential userCredential) { if (!CredWriteW(ref userCredential, 0)) { return Marshal.GetHRForLastWin32Error(); } return 0; } #endregion private static int AddCred() { Credential Cred = new Credential(); string Password = "Password"; Cred.Flags = 0; Cred.Type = CRED_TYPE.GENERIC; Cred.TargetName = "Target"; Cred.UserName = "UserName"; Cred.AttributeCount = 0; Cred.Persist = CRED_PERSIST.ENTERPRISE; Cred.CredentialBlobSize = (uint)Password.Length; Cred.CredentialBlob = Password; Cred.Comment = "Comment"; return CredWrite(Cred); } private static bool CheckError(string TestName, CRED_ERRORS Rtn) { switch(Rtn) { case CRED_ERRORS.ERROR_SUCCESS: Console.WriteLine(string.Format("'{0}' worked", TestName)); return true; case CRED_ERRORS.ERROR_INVALID_FLAGS: case CRED_ERRORS.ERROR_INVALID_PARAMETER: case CRED_ERRORS.ERROR_NO_SUCH_LOGON_SESSION: case CRED_ERRORS.ERROR_NOT_FOUND: case CRED_ERRORS.ERROR_BAD_USERNAME: Console.WriteLine(string.Format("'{0}' failed; {1}.", TestName, Rtn)); break; default: Console.WriteLine(string.Format("'{0}' failed; 0x{1}.", TestName, Rtn.ToString("X"))); break; } return false; } /* * Note: the Main() function is primarily for debugging and testing in a Visual * Studio session. Although it will work from PowerShell, it's not very useful. */ public static void Main() { Credential[] Creds = null; Credential Cred = new Credential(); int Rtn = 0; Console.WriteLine("Testing CredWrite()"); Rtn = AddCred(); if (!CheckError("CredWrite", (CRED_ERRORS)Rtn)) { return; } Console.WriteLine("Testing CredEnum()"); Rtn = CredEnum(null, out Creds); if (!CheckError("CredEnum", (CRED_ERRORS)Rtn)) { return; } Console.WriteLine("Testing CredRead()"); Rtn = CredRead("Target", CRED_TYPE.GENERIC, out Cred); if (!CheckError("CredRead", (CRED_ERRORS)Rtn)) { return; } Console.WriteLine("Testing CredDelete()"); Rtn = CredDelete("Target", CRED_TYPE.GENERIC); if (!CheckError("CredDelete", (CRED_ERRORS)Rtn)) { return; } Console.WriteLine("Testing CredRead() again"); Rtn = CredRead("Target", CRED_TYPE.GENERIC, out Cred); if (!CheckError("CredRead", (CRED_ERRORS)Rtn)) { Console.WriteLine("if the error is 'ERROR_NOT_FOUND', this result is OK."); } } } } "@ #endregion $PsCredMan = $null try { $PsCredMan = [PsUtils.CredMan] } catch { #only remove the error we generate $Error.RemoveAt($Error.Count-1) } if($null -eq $PsCredMan) { Add-Type $PsCredmanUtils } #endregion #region Internal Tools [HashTable] $ErrorCategory = @{0x80070057 = "InvalidArgument"; 0x800703EC = "InvalidData"; 0x80070490 = "ObjectNotFound"; 0x80070520 = "SecurityError"; 0x8007089A = "SecurityError"} function Get-CredType { Param ( [Parameter(Mandatory=$true)][ValidateSet("GENERIC", "DOMAIN_PASSWORD", "DOMAIN_CERTIFICATE", "DOMAIN_VISIBLE_PASSWORD", "GENERIC_CERTIFICATE", "DOMAIN_EXTENDED", "MAXIMUM", "MAXIMUM_EX")][String] $CredType ) switch($CredType) { "GENERIC" {return [PsUtils.CredMan+CRED_TYPE]::GENERIC} "DOMAIN_PASSWORD" {return [PsUtils.CredMan+CRED_TYPE]::DOMAIN_PASSWORD} "DOMAIN_CERTIFICATE" {return [PsUtils.CredMan+CRED_TYPE]::DOMAIN_CERTIFICATE} "DOMAIN_VISIBLE_PASSWORD" {return [PsUtils.CredMan+CRED_TYPE]::DOMAIN_VISIBLE_PASSWORD} "GENERIC_CERTIFICATE" {return [PsUtils.CredMan+CRED_TYPE]::GENERIC_CERTIFICATE} "DOMAIN_EXTENDED" {return [PsUtils.CredMan+CRED_TYPE]::DOMAIN_EXTENDED} "MAXIMUM" {return [PsUtils.CredMan+CRED_TYPE]::MAXIMUM} "MAXIMUM_EX" {return [PsUtils.CredMan+CRED_TYPE]::MAXIMUM_EX} } } function Get-CredPersist { Param ( [Parameter(Mandatory=$true)][ValidateSet("SESSION", "LOCAL_MACHINE", "ENTERPRISE")][String] $CredPersist ) switch($CredPersist) { "SESSION" {return [PsUtils.CredMan+CRED_PERSIST]::SESSION} "LOCAL_MACHINE" {return [PsUtils.CredMan+CRED_PERSIST]::LOCAL_MACHINE} "ENTERPRISE" {return [PsUtils.CredMan+CRED_PERSIST]::ENTERPRISE} } } #endregion #region Dot-Sourced API function Del-Creds { <# .Synopsis Deletes the specified credentials .Description Calls Win32 CredDeleteW via [PsUtils.CredMan]::CredDelete .INPUTS See function-level notes .OUTPUTS 0 or non-0 according to action success [Management.Automation.ErrorRecord] if error encountered .PARAMETER Target Specifies the URI for which the credentials are associated .PARAMETER CredType Specifies the desired credentials type; defaults to "CRED_TYPE_GENERIC" #> Param ( [Parameter(Mandatory=$true)][ValidateLength(1,32767)][String] $Target, [Parameter(Mandatory=$false)][ValidateSet("GENERIC", "DOMAIN_PASSWORD", "DOMAIN_CERTIFICATE", "DOMAIN_VISIBLE_PASSWORD", "GENERIC_CERTIFICATE", "DOMAIN_EXTENDED", "MAXIMUM", "MAXIMUM_EX")][String] $CredType = "GENERIC" ) [Int] $Results = 0 try { $Results = [PsUtils.CredMan]::CredDelete($Target, $(Get-CredType $CredType)) } catch { return $_ } if(0 -ne $Results) { [String] $Msg = "Failed to delete credentials store for target '$Target'" [Management.ManagementException] $MgmtException = New-Object Management.ManagementException($Msg) [Management.Automation.ErrorRecord] $ErrRcd = New-Object Management.Automation.ErrorRecord($MgmtException, $Results.ToString("X"), $ErrorCategory[$Results], $null) return $ErrRcd } return $Results } function Enum-Creds { <# .Synopsis Enumerates stored credentials for operating user .Description Calls Win32 CredEnumerateW via [PsUtils.CredMan]::CredEnum .INPUTS .OUTPUTS [PsUtils.CredMan+Credential[]] if successful [Management.Automation.ErrorRecord] if unsuccessful or error encountered .PARAMETER Filter Specifies the filter to be applied to the query Defaults to [String]::Empty #> Param ( [Parameter(Mandatory=$false)][AllowEmptyString()][String] $Filter = [String]::Empty ) [PsUtils.CredMan+Credential[]] $Creds = [Array]::CreateInstance([PsUtils.CredMan+Credential], 0) [Int] $Results = 0 try { $Results = [PsUtils.CredMan]::CredEnum($Filter, [Ref]$Creds) } catch { return $_ } switch($Results) { 0 {break} 0x80070490 {break} #ERROR_NOT_FOUND default { [String] $Msg = "Failed to enumerate credentials store for user '$Env:UserName'" [Management.ManagementException] $MgmtException = New-Object Management.ManagementException($Msg) [Management.Automation.ErrorRecord] $ErrRcd = New-Object Management.Automation.ErrorRecord($MgmtException, $Results.ToString("X"), $ErrorCategory[$Results], $null) return $ErrRcd } } return $Creds } function Read-Creds { <# .Synopsis Reads specified credentials for operating user .Description Calls Win32 CredReadW via [PsUtils.CredMan]::CredRead .INPUTS .OUTPUTS [PsUtils.CredMan+Credential] if successful [Management.Automation.ErrorRecord] if unsuccessful or error encountered .PARAMETER Target Specifies the URI for which the credentials are associated If not provided, the username is used as the target .PARAMETER CredType Specifies the desired credentials type; defaults to "CRED_TYPE_GENERIC" #> Param ( [Parameter(Mandatory=$true)][ValidateLength(1,32767)][String] $Target, [Parameter(Mandatory=$false)][ValidateSet("GENERIC", "DOMAIN_PASSWORD", "DOMAIN_CERTIFICATE", "DOMAIN_VISIBLE_PASSWORD", "GENERIC_CERTIFICATE", "DOMAIN_EXTENDED", "MAXIMUM", "MAXIMUM_EX")][String] $CredType = "GENERIC" ) if("GENERIC" -ne $CredType -and 337 -lt $Target.Length) #CRED_MAX_DOMAIN_TARGET_NAME_LENGTH { [String] $Msg = "Target field is longer ($($Target.Length)) than allowed (max 337 characters)" [Management.ManagementException] $MgmtException = New-Object Management.ManagementException($Msg) [Management.Automation.ErrorRecord] $ErrRcd = New-Object Management.Automation.ErrorRecord($MgmtException, 666, 'LimitsExceeded', $null) return $ErrRcd } [PsUtils.CredMan+Credential] $Cred = New-Object PsUtils.CredMan+Credential [Int] $Results = 0 try { $Results = [PsUtils.CredMan]::CredRead($Target, $(Get-CredType $CredType), [Ref]$Cred) } catch { return $_ } switch($Results) { 0 {break} 0x80070490 {return $null} #ERROR_NOT_FOUND default { [String] $Msg = "Error reading credentials for target '$Target' from '$Env:UserName' credentials store" [Management.ManagementException] $MgmtException = New-Object Management.ManagementException($Msg) [Management.Automation.ErrorRecord] $ErrRcd = New-Object Management.Automation.ErrorRecord($MgmtException, $Results.ToString("X"), $ErrorCategory[$Results], $null) return $ErrRcd } } return $Cred } function Write-Creds { <# .Synopsis Saves or updates specified credentials for operating user .Description Calls Win32 CredWriteW via [PsUtils.CredMan]::CredWrite .INPUTS .OUTPUTS [Boolean] true if successful [Management.Automation.ErrorRecord] if unsuccessful or error encountered .PARAMETER Target Specifies the URI for which the credentials are associated If not provided, the username is used as the target .PARAMETER UserName Specifies the name of credential to be read .PARAMETER Password Specifies the password of credential to be read .PARAMETER Comment Allows the caller to specify the comment associated with these credentials .PARAMETER CredType Specifies the desired credentials type; defaults to "CRED_TYPE_GENERIC" .Length) #CRED_MAX_DOMAIN_TARGET_NAME_LENGTH { [String] $Msg = "Target field is longer ($($Target.Length)) than allowed (max 337 characters)" [Management.ManagementException] $MgmtException = New-Object Management.ManagementException($Msg) [Management.Automation.ErrorRecord] $ErrRcd = New-Object Management.Automation.ErrorRecord($MgmtException, 666, 'LimitsExceeded', $null) return $ErrRcd } if([String]::IsNullOrEmpty($Comment)) { $Comment = [String]::Format("Last edited by {0}\{1} on {2}", $Env:UserDomain, $Env:UserName, $Env:ComputerName) } [String] $DomainName = [Net.NetworkInformation.IPGlobalProperties]::GetIPGlobalProperties().DomainName [PsUtils.CredMan+Credential] $Cred = New-Object PsUtils.CredMan+Credential switch($Target -eq $UserName -and ("CRED_TYPE_DOMAIN_PASSWORD" -eq $CredType -or "CRED_TYPE_DOMAIN_CERTIFICATE" -eq $CredType)) { $true {$Cred.Flags = [PsUtils.CredMan+CRED_FLAGS]::USERNAME_TARGET} $false {$Cred.Flags = [PsUtils.CredMan+CRED_FLAGS]::NONE} } $Cred.Type = Get-CredType $CredType $Cred.TargetName = $Target $Cred.UserName = $UserName $Cred.AttributeCount = 0 $Cred.Persist = Get-CredPersist $CredPersist $Cred.CredentialBlobSize = [Text.Encoding]::Unicode.GetBytes($Password).Length $Cred.CredentialBlob = $Password $Cred.Comment = $Comment [Int] $Results = 0 try { $Results = [PsUtils.CredMan]::CredWrite($Cred) } catch { return $_ } if(0 -ne $Results) { [String] $Msg = "Failed to write to credentials store for target '$Target' using '$UserName', '$Password', '$Comment'" [Management.ManagementException] $MgmtException = New-Object Management.ManagementException($Msg) [Management.Automation.ErrorRecord] $ErrRcd = New-Object Management.Automation.ErrorRecord($MgmtException, $Results.ToString("X"), $ErrorCategory[$Results], $null) return $ErrRcd } return $Results } #endregion #region Cmd-Line functionality function CredManMain { #region Adding credentials if($AddCred) { if([String]::IsNullOrEmpty($User) -or [String]::IsNullOrEmpty($Pass)) { Write-Host "You must supply a user name and password (target URI is optional)." return } # may be [Int32] or [Management.Automation.ErrorRecord] [Object] $Results = Write-Creds $Target $User $Pass $Comment $CredType $CredPersist if(0 -eq $Results) { [Object] $Cred = Read-Creds $Target $CredType if($null -eq $Cred) { Write-Host "Credentials for '$Target', '$User' was not found." return } if($Cred -is [Management.Automation.ErrorRecord]) { return $Cred } [String] $CredStr = @" Successfully wrote or updated credentials as: UserName : $($Cred.UserName) Password : $($Cred.CredentialBlob) Target : $($Cred.TargetName.Substring($Cred.TargetName.IndexOf("=")+1)) Updated : $([String]::Format("{0:yyyy-MM-dd HH:mm:ss}", $Cred.LastWritten.ToUniversalTime())) UTC Comment : $($Cred.Comment) "@ Write-Host $CredStr return } # will be a [Management.Automation.ErrorRecord] return $Results } #endregion #region Removing credentials if($DelCred) { if(-not $Target) { Write-Host "You must supply a target URI." return } # may be [Int32] or [Management.Automation.ErrorRecord] [Object] $Results = Del-Creds $Target $CredType if(0 -eq $Results) { Write-Host "Successfully deleted credentials for '$Target'" return } # will be a [Management.Automation.ErrorRecord] return $Results } #endregion #region Reading selected credential if($GetCred) { if(-not $Target) { Write-Host "You must supply a target URI." return } # may be [PsUtils.CredMan+Credential] or [Management.Automation.ErrorRecord] [Object] $Cred = Read-Creds $Target $CredType if($null -eq $Cred) { Write-Host "Credential for '$Target' as '$CredType' type was not found." return } if($Cred -is [Management.Automation.ErrorRecord]) { return $Cred } [String] $CredStr = @" Found credentials as: UserName : $($Cred.UserName) Password : $($Cred.CredentialBlob) Target : $($Cred.TargetName.Substring($Cred.TargetName.IndexOf("=")+1)) Updated : $([String]::Format("{0:yyyy-MM-dd HH:mm:ss}", $Cred.LastWritten.ToUniversalTime())) UTC Comment : $($Cred.Comment) "@ Write-Host $CredStr } #endregion #region Reading all credentials if($ShoCred) { # may be [PsUtils.CredMan+Credential[]] or [Management.Automation.ErrorRecord] [Object] $Creds = Enum-Creds if($Creds -split [Array] -and 0 -eq $Creds.Length) { Write-Host "No Credentials found for $($Env:UserName)" return } if($Creds -is [Management.Automation.ErrorRecord]) { return $Creds } foreach($Cred in $Creds) { [String] $CredStr = @" UserName : $($Cred.UserName) Password : $($Cred.CredentialBlob) Target : $($Cred.TargetName.Substring($Cred.TargetName.IndexOf("=")+1)) Updated : $([String]::Format("{0:yyyy-MM-dd HH:mm:ss}", $Cred.LastWritten.ToUniversalTime())) UTC Comment : $($Cred.Comment) "@ if($All) { $CredStr = @" $CredStr Alias : $($Cred.TargetAlias) AttribCnt : $($Cred.AttributeCount) Attribs : $($Cred.Attributes) Flags : $($Cred.Flags) Pwd Size : $($Cred.CredentialBlobSize) Storage : $($Cred.Persist) Type : $($Cred.Type) "@ } Write-Host $CredStr } return } #endregion #region Run basic diagnostics if($RunTests) { [PsUtils.CredMan]::Main() } #endregion } #endregion CredManMain } cd C:\Temp $MUser = $env:username $NASUser = 'user' $NASAdmin = 'admin' if($MUser -eq $NASUser) { add-creds -AddCred -Target '192.168.0.5' -User 'nasuser' -Pass 'MyPassword' -Comment 'NAS' -CredType 'DOMAIN_PASSWORD' add-creds -AddCred -Target '192.168.0.6' -User 'nasuser' -Pass 'MyPassword' -Comment 'NAS'-CredType 'DOMAIN_PASSWORD' add-creds -AddCred -Target '192.168.0.7' -User 'nasuser' -Pass 'MyPassword' -Comment 'NAS'-CredType 'DOMAIN_PASSWORD' add-creds -AddCred -Target '192.168.0.8' -User 'nasuser' -Pass 'MyPassword' -Comment 'NAS'-CredType 'DOMAIN_PASSWORD' add-creds -AddCred -Target '192.168.0.3' -User 'admin' -Pass 'MyPassword' -Comment 'Download Laptop'-CredType 'DOMAIN_PASSWORD' add-creds -AddCred -Target '192.168.0.24' -User 'admin' -Pass 'MyPassword' -Comment 'office'-CredType 'DOMAIN_PASSWORD' add-creds -AddCred -Target '192.168.0.20' -User 'admin' -Pass 'MyPassword' -Comment 'alfie'-CredType 'DOMAIN_PASSWORD' } if($MUser -eq $NASAdmin) { add-creds -AddCred -Target '192.168.0.5' -User 'nasadmin' -Pass 'MyPassword' -Comment 'NAS' -CredType 'DOMAIN_PASSWORD' add-creds -AddCred -Target '192.168.0.6' -User 'nasadmin' -Pass 'MyPassword' -Comment 'NAS'-CredType 'DOMAIN_PASSWORD' add-creds -AddCred -Target '192.168.0.7' -User 'nasadmin' -Pass 'MyPassword' -Comment 'NAS'-CredType 'DOMAIN_PASSWORD' add-creds -AddCred -Target '192.168.0.8' -User 'nasadmin' -Pass 'MyPassword' -Comment 'NAS'-CredType 'DOMAIN_PASSWORD' add-creds -AddCred -Target '192.168.0.3' -User 'admin' -Pass 'MyPassword' -Comment 'Download Laptop'-CredType 'DOMAIN_PASSWORD' add-creds -AddCred -Target '192.168.0.24' -User 'admin' -Pass 'MyPassword' -Comment 'office'-CredType 'DOMAIN_PASSWORD' add-creds -AddCred -Target '192.168.0.20' -User 'admin' -Pass 'MyPassword' -Comment 'alfie'-CredType 'DOMAIN_PASSWORD' } $net = new-object -ComObject WScript.Network $net.MapNetworkDrive("z:", "\\192.168.0.5\TV_Series", $true) $net.MapNetworkDrive("w:", "\\192.168.0.5\Movies", $true) $net.MapNetworkDrive("l:", "\\192.168.0.6\TV_Series", $true) $net.MapNetworkDrive("m:", "\\192.168.0.6\Movies", $true) $net.MapNetworkDrive("v:", "\\192.168.0.6\Music", $true) $net.MapNetworkDrive("a:", "\\192.168.0.6\Archive", $true) $net.MapNetworkDrive("s:", "\\192.168.0.6\Documents", $true) $net.MapNetworkDrive("u:", "\\192.168.0.6\Pictures", $true) $net.MapNetworkDrive("t:", "\\192.168.0.6\Programs", $true) $net.MapNetworkDrive("y:", "\\192.168.0.7\TV_Series", $true) $net.MapNetworkDrive("n:", "\\192.168.0.7\Movies", $true) $net.MapNetworkDrive("q:", "\\192.168.0.8\TV_Series", $true) $net.MapNetworkDrive("r:", "\\192.168.0.8\Movies", $true) New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" -Name "{F42EE2D3-909F-4907-8871-4C22FC0BF756}" -PropertyType "String" -Value '\\192.168.0.6\documents' New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" -Name "Personal" -PropertyType "String" -Value '\\192.168.0.6\documents' -Force
Sours: https://dailysysadmin.com/KB/Article/2398/powershell-script-to-add-credentials-to-windows-credential-manager-and-map-some-drives/

To credential powershell add manager credentials

Managing Saved Passwords Using Windows Credential Manager

Windows Credential Manager allows saving credentials (usernames and passwords) to access network resources, websites, and apps. With Windows Credential Manager, you can connect to remote resources automatically without entering your password. Apps can access Credential Manager themselves and use saved passwords.

Using Credential Manager to Store Passwords in Windows

The Credential Manager appeared in Windows 7 and is positioned as quite a safe place to keep your passwords.

The Credential Manager on Windows 10 can keep the following account types:

  • Windows Credentials – credentials to log on Windows or to access remote computers, saved passwords for RDP connections, passwords for websites with the integrated Windows authentication support, etc;
  • Certificate-Based Credentials – to authenticate using smart cards;
  • Generic Credentials – are used by third-party apps compatible with the Credential Manager;
  • Web Credentials – saved passwords in Edge and IE, Microsoft apps (MS Office, Teams, Outlook, Skype, etc.).

For example, if you enable the “” option when accessing a shared network folder, the password you enter will be saved in the Credential Manager.

save credentials to access network shared in windows credential manager

In the same way, a password to connect to a remote RDP/RDS host is saved in the Remote Desktop Connection (mstsc.exe) client.

save RDP password to Windows Credential Manager

Also, the Credential Manager keeps user passwords if they are saved using the runas /savecred command.

You can access the Credential Manager in Windows 10 from the classic Control Panel ().

As you can see, there are two passwords in the Credential Manager we saved earlier.

list saved credential in windows

A saved password for an RDP connection is specified in the format.

Here you can add a saved credential, edit it (you cannot view a saved password in the graphic interface), or delete any of the entries.

Also, you can use the classic interface of Stored User Names and Passwords, to manage saved passwords. To call it, run the command below:

Stored User Names and Passwords on Windows 10

Here you can also manage saved credentials, and it has some backup and restore features for the Credential Manager (you can use them to transfer a Credential Manager database to another computer).

The tool is used to manage the Credential Manager from the command prompt. For example, to display a list of saved Windows Credentials, run this command:

vaultcmd - manage saved windows credentials command prompt

Credential schema: Windows Domain Password Credential Resource: Domain:target=mun-dc01 Identity: RESDOM\j.brion Hidden: No Roaming: No Property (schema element id,value): (100,3) Property (schema element id,value): (101,SspiPfAc)

The following command will delete all saved RDP passwords from the Credential Manager:

All saved passwords are stored in the Windows Vault. Windows Vault is a protected store to keep secrets, passwords, and other sensitive user information. In Windows Vault, data are structured and look like a set of entries that belong to a Vault scheme. The set of encryption keys for Windows Vault entries is stored in the Policy.vpol file.

For the domain users, it is located in .

For the local users, you can find it in .

Policy.vpol - Windows Vault Policy File

The VaultSvc service must be running when using the Credential Manager:

If the service is disabled, you will see the following error when trying to access the Credential Manager:

Credential Manager Error The Credential Manager Service is not running. You can start the service manually using the Services snap-in or restart your computer to start the service. Error code: 0x800706B5 Error Message: The interface is unknown.

If you want to prevent users from saving network passwords in the Credential Manager, enable the Network access: Do not allow storage of passwords and credentials for network authentication GPO option under Computer Configuration -> Windows Settings -> Security Settings -> Local Policies -> Security Options.

GPO: Network access: Do not allow storage of passwords and credentials for network authentication

Then if a user tries to save the password to the Windows Vault store, they will see the following error:

Credential Manager Error Unable to save credentials. To save credentials in this vault, check your computer configuration. Error code: 0x80070520 Error Message: A specified logon session does not exist. It may already have been terminated.

Accessing Windows Credential Manager from PowerShell

Windows don’t have built-in cmdlets to access the PasswordVault store from PowerShell. But you can use the CredentialManager module from the PowerShell gallery.

Install the module:

You can display a list of cmdlets in the CredentialManager module:

CredentialManager powershell module

The module has only 4 cmdlets:

  • – to get credentials from the Windows Vault;
  • – to generate a random password;
  • – to add credentials;
  • – to remove credentials.

In order to add new credentials to the Windows Credential Manager, run this command:

Create a credential object for PowerShell automation using New-StoredCredential

To make sure if any saved user credentials exist in the Credential Manager:

You can use saved passwords from the Credential Manager in your PowerShell scripts. For example, I can get a saved name and password from the Windows Vault as a PSCredential object and connect to Exchange Online from PowerShell:

Also, note a new PowerShell Secret Management module you can use to securely store passwords in Windows. It supports a number of password vaults: KeePass, LastPass, HashiCorp Vault, Azure Key Vault, Bitwarden.

To remove credentials from Windows Vault, run this command:

You cannot display passwords as plain text using built-in CLI tools. But, you can use Mimikatz-like utilities to get saved passwords from  as plain text (see the example here).

Sours: http://woshub.com/saved-passwords-windows-credential-manager/
How to save login credentials to a file using PowerShell

Pants. His already swollen member was right at the wet waiting mouth of the girl. She quickly clasped the head with her lips and took the whole pin into her mouth with pleasure.

You will also be interested:

The doctors filled up our cards and freed us for a year from physical education, and. They said that if we wanted them, they would gladly help us in the next school. What I'm going to tell you now, maybe, to someone it will seem a mere trifle. This adventure made a very significant impression on me at one time.



41705 41706 41707 41708 41709