cmdkey in PowerShell doesn't work when run as a logon script?
Asked Answered
K

5

6

Trying is use cmdkey in a PowerShell logon script to store credentials in the credential manager. When the script is run from PowerShell ISE everything works, but when it's run as a logon script via Group Policy everything but cmdkey works. Cannot for the life of me figure out why cmdkey will work everywhere except when the script run on logon.

# Checks if CRM for Outlook is isntalled by checking the folder path
$installed = Test-Path "C:\Program Files (x86)\Microsoft Dynamics CRM"
# Checks if the CRM has already been configured using the CoreConfigured registry entry
$configured = Get-ItemProperty -Path HKCU:\software\Microsoft\MSCRMClient -Name     "CoreConfigured"

# If CRM is installed and not configured, configure it, if CRM is not installed or     installed and configured, exit
If ($installed -eq "True" -and $configured.CoreConfigured -ne 1) { 

    $message1 = New-object -ComObject Wscript.Shell
    $message1.Popup("Preparing to configure Microsoft CRM for Outlook, please make sure     Outlook is closed.",10,"Systems")

    # Prompts user for email address and Password to configure CRM for Outlook
    $c = Get-Credential -Message "To confgiure CRM, please enter your email address and password:"

    # puts user credentials into Windows Credential Manager using required CRM URLs 
    cmdkey /generic:Microsoft_CRM_https://disco.crm.dynamics.com/ /user: $c.Username  /pass: $c.Password | Out-Null
    cmdkey /generic:Microsoft_CRM_https://disco.crm4.dynamics.com/ /user: $c.Username /pass: $c.Password | Out-Null


    $message2 = New-Object -ComObject Wscript.Shell
    $message2.Popup("Please wait, a notification will appear when the configuration is complete.",10,"Systems")

    # Silenty runs the CRM configuration Wizard with custom XML file
    $exe = "C:\Program Files (x86)\Microsoft Dynamics CRM\Client\ConfigWizard\Microsoft.Crm.Application.Outlook.ConfigWizard.exe"
   &$exe -p /Q /i 'C:\Program Files (x86)\Microsoft Dynamics CRM\Default_Client_Config.xml' /xa /l 'c:\temp\crminstall.txt' | Out-Null

    $message3 = New-Object -ComObject Wscript.Shell
    $message3.Popup("Configuration complete! You may now open Outlook!",10,"Systems")

} 
else {
    exit    
}
Keratoid answered 19/8, 2014 at 12:45 Comment(3)
what is cmdkey? A cmdlet? A program? Where is it on the disk?Kinematograph
cmdkey is a command line program located in C:\Windows\System32\cmdkey.exe used to Create, lists and delete stored user credentials. technet.microsoft.com/en-us/library/cc754243.aspxKeratoid
Even though it should work It is a good practice anyway to use the full path to exe. Just in case... never know who will screw with Path. $env:SystemRoot\System32\cmdkey.exe. I have also seem with exe's that you need to wrap code like this $c.Username in $() to be sure its evaluated properly $($c.Username). If you close ISE and run the code from a new ISE session does it work? Clients wont have access to your profile information you might have in powershell as well.Silken
E
1

I imagine cmdkey is using Microsoft's Data Protection API (DPAPI) to encrypt credentials so only the current user can retrieve them. You can't use this API unless the user's session is loaded. When your script runs, it may be too early in the logon process for the security information the DPAPI needs is loaded. I'm not sure how logon scripts work, but try putting a delay in your logon script until you get a value back.

Here's the PowerShell code that encrypts with the DPAPI:

$scope = [Security.Cryptography.DataProtectionScope]::CurrentUser
$encryptedBytes = [Security.Cryptography.ProtectedData]::Protect( $plainBytes, $null, $scope )
$decryptedBytes = [Security.Cryptography.ProtectedData]::Unprotect( $encryptedBytes, $null, 0 )

Add a loop in your logn script that tries to encrypt/decrypt some random array of bytes until it succeeds.

Enigmatic answered 1/9, 2014 at 3:14 Comment(0)
S
1

I had the same issue: cmdkey was not working in Powershell when run as a User Logon Script.

In my case the issue was related to the user's group membership. The user was a member of the group "Power Users", but not a member of the group "Users" (or any other group).

According to this article from Microsoft, the group "Power Users" has "no default user rights", while the group "Users" has rights to "perform common tasks, such as running applications, using local and network printers".

The solution was to add my user(s) to the group "Users". This immediately solved the issue and allowed cmdkey to work in Powershell Logon Scripts.

Smallman answered 23/6, 2016 at 12:40 Comment(0)
R
1

I had this same problem with a PowerShell GPO logon script calling cmdkey.exe. The credentials populated into Credential Manager for Users, but Administrators the credentials did not show up. I found out that the credentials are saving in Credential Manager, but for the elevated user. If you run cmdkey /list in an elevated command prompt you will see the credentials there.

Recognizee answered 1/8, 2017 at 17:38 Comment(0)
T
0

This is obviously not a best practice (Windows would vastly prefer that you the user who is logging in has all the needed permissions, rather than caching things with cmdkey).

HOWEVER, if some poor soul is stuck with the same problem, and none of the above solutions works for them, then you might want to try using Scheduled Tasks instead.

Under Task Scheduler, create a task, and set it to run as BUILTIN\Users (or whichever group the users who are going to be needing the credentials will log in as, you may need multiple tasks): DO NOT SELECT "Run with highest privileges" or you will only be able to access the credentials from processes running with administrator permissions.

Trigger it "At log in of any user", and then you can set it to retry on fail. This is verified still working in Server 2022.

From the command line:

sctasks /create /sc ONLOGON /tn "Name Here" /tr "setCredsAtLogin.bat" /ru "Users" 
Tercel answered 29/7 at 17:20 Comment(0)
E
0

Here is the solution I use to get rid of Microsoft's Data Protection API (DPAPI) when managing secure string with ConvertFrom-SecureString or ConvertTo-SecureString cmdlet : you have to use "-Key" argument.

For example :

  1. To get secure string password :

$USER_PASSWORD_SECURE_STRING = ConvertFrom-SecureString $USER_PASSWORD_SECURE -Key (1..16)

  1. Then, to get plain text password :

$USER_PASSWORD_SECURE = ConvertTo-SecureString $USER_PASSWORD_SECURE_STRING -Key (1..16) $BSTRP = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($USER_PASSWORD_SECURE) $USER_PASSWORD_PLAINTEXT = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTRP)

I use this solution succcessfully to restore saved credentials with a schedule task (powershell script that uses cmdkey) at logon of all users

Hope this help (spent myself a lot of time to this problem)...

Egbert answered 8/8 at 9:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.