Processing a PowerShell SecureString as a parameter or console entry - powershell

I'm having a lot of difficulty with a PowerShell script that I'm trying to call a DirectoryServices query from. Currently, if I do a
$password = read-host "Password" -asSecureString
and subsequently
$credential = New-Object System.Management.Automation.PSCredential $username,$password
everything works fine. However if I try to pass the string parameter with a param($password) and then convert it to a secure string with this code:
$password = ConvertTo-SecureString -AsPlainText -Force $password
After extensive debugging I can see this is working fine in terms of converting the string to a securestring, but I get a bad user/password from DirectoryServices when I use the parameter. Everything works fine when read from the console. Any ideas on what I can do to accept a parameter OR take console input in the absence of a parameter?
This is what I was hoping would work, but doesn't:
if($password -eq $null) {
$password = read-host "Password" -asSecureString
} else {
$password = ConvertTo-SecureString -AsPlainText -Force $password
}
$credential = New-Object System.Management.Automation.PSCredential $username,$password

I recently created a script and was running into the same issue. The work around I found in my case was the following:
#Prompts for the username/password, enter the username in the form of DomainName\UserName
$Credential = get-credential
#Converts the password to clear text to pass it through correctly as passing through a secure string does not work.
$Password = $credential.GetNetworkCredential().password
#Converts the $Credential to just the DomainName/UsernName.
$Account = $credential.UserName
Hopefully this will work in your situation

Related

How to retrieve Password from PSCredential in a .cred file

I have two functions, Save Credential to create a .cred file:
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList ($Username, $PWord)
$cred.Password | Out-File "some\path\$($cred.Username).cred" -Force
and Get Credential to retrieve the password:
$string = Get-Content "some\path\$($Username).cred" | ConvertTo-SecureString
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList $Username, $string
return $cred
I cannot for the life of me figure out how to retrieve the password from the .cred file that I created. The errors I get are:
ConvertTo-SecureString: Input String was not in the correct format
New-Object: Exception calling .actor with 2 arguments. Cannot process argument because the value of argument "password" is null. change the value of argument password to a non-null value
What version are you bound to? I might not be following properly, but it looks like you don't care about the whole credential and just want the password, so couldn't it just be:
#set
$pwd = "replace me"
$securepwd = $pwd | ConvertTo-SecureString -AsPlainText -Force
$encryptedpwd = $securepwd | ConvertFrom-SecureString
Out-File -FilePath C:\temp\Reference.cred -InputObject $encryptedpwd
then
#get
$securepwd = (Get-Content -Path C:\temp\Reference.cred) | ConvertTo-SecureString
#commented out 3 lines shows how to decrypt in case you want to view it/verify it, but isn't necessary
#$Marshal = [System.Runtime.InteropServices.Marshal]
#$Bstr = $Marshal::SecureStringToBSTR($securepwd)
#$pswd = $Marshal::PtrToStringAuto($Bstr)
#$Marshal::ZeroFreeBSTR($Bstr)
$RunAs = New-Object System.Management.Automation.PSCredential ('Domain\Account', $securepwd)
I'm not as good as most folks on here though, just giving it a stab.

How can I give a password as parameter using the Graph API for Azure-AD and Intune?

Following the example found here: https://github.com/microsoftgraph/powershell-intune-samples/blob/master/Authentication/Auth_From_File.ps1
More specifically:
$UserPassword = get-Content "$Password" | ConvertTo-SecureString
$userCredentials = new-object Microsoft.IdentityModel.Clients.ActiveDirectory.UserPasswordCredential -ArgumentList $userUPN,$UserPassword
$authResult = [Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContextIntegratedAuthExtensions]::AcquireTokenAsync($authContext, $resourceAppIdURI, $clientid, $userCredentials).Result;
I've tried the following:
$UserPassword = ConvertTo-SecureString -String $Password -AsPlainText -Force
$userCredentials = new-object Microsoft.IdentityModel.Clients.ActiveDirectory.UserPasswordCredential -ArgumentList $userUPN,$UserPassword
$authResult = [Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContextIntegratedAuthExtensions]::AcquireTokenAsync($authContext, $resourceAppIdURI, $clientid, $userCredentials).Result;
However, I've been getting the error that
Authorization Access Token is null, please re-run authentication...
which can be found further in the code.
if($authResult.AccessToken){
[...]
Write-Host
Write-Host "Authorization Access Token is null, please re-run authentication..." -ForegroundColor Red
Write-Host
break
Am I correct in thinking that I probably need to give the password in a different way?
Alright, I think I found whatever went wrong. I tried running another script and had to manually enter the credentials. This prompted me to accept a whole lot of permissions from Microsoft. I think that was the problem. This code now works:
$userId = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.UserIdentifier" -ArgumentList ($User, "OptionalDisplayableId")
$UserPassword = ConvertTo-SecureString -String $Password -AsPlainText -Force
$userCredentials = new-object Microsoft.IdentityModel.Clients.ActiveDirectory.UserPasswordCredential -ArgumentList $userUPN,$UserPassword
$authResult = [Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContextIntegratedAuthExtensions]::AcquireTokenAsync($authContext, $resourceAppIdURI, $clientid, $userCredentials).Result;
Still, thank you Mathias and Marc for trying to help :)

How to handle PowerShell Secure Strings

How do I properly enter and store a secure password? I am needing to Convert it from Secure in order to put in to JSON to get a REST token.
My example is:
PS C:\Temp> $secpass = Read-Host -assecurestring "Please enter password";
Please enter password: *****
PS C:\Temp> echo $secpass
System.Security.SecureString
PS C:\Temp> $pass =
ConvertFrom-SecureString $secpass
PS C:\Temp> echo $pass
01000000d08c9ddf0115d1118c7a00c04fc297eb010000004fe37b5a39a93542a74298c3740cae0b0000000002000000000003660000c00000001000000096aa9947681adf56ce6f9fd2d9ced2140000000004800000a0000000100000006bbff8b1e2115682e9be4c775d8372ee10000000b80a4a99147901275a9080c257712b1914000000010eabc8c134837751dbd2d648dbbca1f7335e9f
PS C:\Temp>
I want to run the ConvertFrom-SecureString and get my simple plain text password back.
EDIT;
I have the following function that obtains a REST Token:
function Get-AuthToken {
Param(
[string]$server,
[string]$username,
[securestring]$password
)
$creds = #{
username = $username
password = $password
grant_type = "password"
};
Invoke-RestMethod -Method Post "$server/api/token" -Body $creds
}
To build $creds correctly the password needs to be in plain text.
Furthermore I also have the following to cover the case where password string is not given when the script is run:
If(!$Password) {
[ValidatePattern("\w+")]$password = Read-Host -assecurestring "Please enter password";
}
As per first answer given here Convert a secure string to plain text I have tried to add the following before calling the Get-AuthToken function:
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Password)
$unsecurePassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
$response = Get-AuthToken -username $User -password $unsecurePassword -server $server
If I do a Write-Host $unsecurePassword I can see the correct string however the Get-AuthToken fails authentication.
EDIT 2:
If I change the function to :
function Get-AuthToken {
Param(
[string]$server,
[string]$username,
[string]$password
)
$creds = #{
username = $username
password = $password
grant_type = "password"
};
Invoke-RestMethod -Method Post "$server/api/token" -Body $creds
}
Which is making the $password parameter a string rather than a secure string then it works however don't believe this is best practice since Visual Studio Code is complaining.
It's not recommended for production systems but try this:
$secpass = Read-Host -assecurestring "Please enter password"
$credentials = New-Object System.Net.NetworkCredential("UserTest", $secpass, "Domain")
$credentials.Password
You cannot do that with ConvertFrom-SecureString

Invoke-RestMethod special characters in credentials

I'm trying to make an API call using a password that contains an "#" character and I'm getting invalid credentials.
$Password = ConvertTo-SecureString -String $Password -AsPlainText -Force
$Creds = New-Object –TypeName System.Management.Automation.PSCredential –ArgumentList $Username, $Password
Invoke-RestMethod -Uri ("http://contoso") -Credential $Creds
You have to escape the special chars or put the password in single quotes.
But as #Lieven Keersmaekers said - the # is no special char.
So you have to look if you have an other problem :)
Examples:
$Password = '$up#r' // -- This works (single quotes wont interpret the "special chars")
$Password = "`$up#r" // -- This works because you escaped the characters
$Password = "$up#r" // -- This wont work
More Examples:
PS > $Password = "H#ppy"
$Password
H#ppy
PS > $Password = '$uper H#ppy'
$Password
$uper H#ppy
PS > $Password = "`$uper H#ppy"
$Password
$uper H#ppy
hava a look at this Site
Greetz Eldo.Ob
it was not the # causing the problem it was in-fact a $ in the password causing the problem.
I added single quotes to my password and it works.
Thanks for the suggestions.

Using Password Variable in System.DirectoryServices.ActiveDirectory context

Does anyone know how to use password in System.DirectoryServices.ActiveDirectory context. Password is stored in a file.
$UserName="DomainName.com\JohnP"
$PassFile="C:\Temp\Pass.PPP"
$password = get-content $PassFile | ConvertTo-SecureString -AsPlainText -Force
$creds = new-object -typename System.Management.Automation.PSCredential("$UserName",$password)
$a = new-object System.DirectoryServices.ActiveDirectory.DirectoryContext("Forest", "MyForest.com",$UserName,$Password)
It always returns "Server rejected the credentials". If I store password in $Password variable, it works. For example, below code works:
$UserName="DomainName.com\JohnP"
$PassFile="C:\Temp\Pass.PPP"
$password = "MyPassword"
$creds = new-object -typename System.Management.Automation.PSCredential("$UserName",$password)
$a = System.DirectoryServices.ActiveDirectory.DirectoryContext("Forest", "MyForest.com",$UserName,$Password)
Can someone please help as to how to use password from a file and then use with System.DirectoryServices.ActiveDirectory context.
Many thanks!
Nratwa
A [PSCredential] stores the password as a secure string, so it's encrypted.
To get the unencrypted password value:
$creds.GetNetworkCredential().Password