Entering password automatically in enter-pssession - powershell

Im currently making a Powershell Script in Powershell ISE that is going to be used for entering all of the servers we're hosting and grabbing all the users from the servers ActiveDirectory. To do that I have to connect to all servers automatically (There are many servers but only 42 that we need to access). Let me explain what I've done so far and what te actual problem is.
So as you know there are many different servers, so we had to read all the server IP:S/Usernames/Passwords from a excel file that a colleague made, and then place them into arrays.
From there, we made a for loop looking like this:
for ($S = 0; $ -le $ServerAdressArray.Length; $S++)
{
if ($ServerAdressArray[$S] -like '192.168.*.10')
{
GetData($S)
}
}
What it does is going through the array filtering out all the local IP-Adresses from the array, if it finds a local ip adress, it runs the GetData function which looks like this at the moment:
function GetData([int]$arg1)
{
Enter-PSsession -ComputerName $ServerAdressArray[$arg1] -Credential $UsernamesArray[$arg1] $PasswordArray[$arg1]
}
What I want it to do is to use the row number it found the local IP-Adress on and then use that number to locate the correct Username and Password to log in with on that specific server.
The problem is, i have to enter the password in powershell for every single server. And i just want to enter it on the same line as Enter-PSSession.
If you want more specific details, let me know. Also, I'm new to this type of scripting so if you cold be as basic as possible in your explanations that would be great :)
Thank you.

The problem here is how you're passing the "Credential" parameter. It should be of type PSCredential.
Assuming you've stored the username and password in clear text in your file you can create a credential object directly:
New-Object PSCredential -ArgumentList #("a", ("p"|ConvertTo-SecureString -AsPlainText -Force))
For your example :
Enter-PSsession -ComputerName $ServerAdressArray[$arg1] -Credential (New-object PSCredential -ArgumentList #($UsernamesArray[$arg1], ($PasswordArray[$arg1]|ConvertTo-secureString -AsPlainText -Force)))
However; if you're interested in returning some data for each server back to the executing host (e.g. for further processing) you wouldn't want to enter the session, you would want to use Invoke-command instead.
E.g.
Invoke-command -ComputerName $ServerAdressArray[$arg1] -Credential (New-object PSCredential -ArgumentList #($UsernamesArray[$arg1], ($PasswordArray[$arg1]|ConvertTo-secureString -AsPlainText -Force))) -Scriptblock $scriptblockToExecute

Hi CmdrTchort/Richard (:P). Thank you for the answer!
All the passwords in the excelfile are encrypted for security reasons. I am currently working on a function that will decrypt the password before using it.
I've looked around a bit more on the internet and i stumbled across this post:
Using PowerShell credentials without being prompted for a password
I tried what Jeroen Landheer said and the function now looks like this:
function GetData(int[$arg1])
{
$secstr = New-Object -TypeName System.Security.Securestring
$PasswordArray[$arg1].ToCharArray() | ForEach-Object {$secstr.AppendChar($_)}
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $secstr
$session = new-pssession -computername $ServerAdressArray[$arg1] -credential $UserNameArray[$arg1] $PasswordArray[$arg1]
}
The Prompt is appearing so the password hasn't automatically been filled in and when i close the prompt(s). I get this error:
New-PSSession : A positional parameter cannot be found that accepts argument '(encryptedpassword)'.
At C:\xxxxxxx\xxxxx\xxxxxx\superfile.ps1:109 char:16
+ ... $session = new-pssession -computername $ServerAdressArray[$arg1] -cr ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [New-PSSession], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.NewPSSessionCommand
Do I have to enter some kind of positional parameter or does it now work because its encrypted?

Related

The Using variable is not supported in the script function or filter

I am running into a little issue, I have generated runbooks using powershell.
One of them connects to Vmware using a build up similar to this
The code
TempFunction{
connects to vmware using VMuser1 credentials
runs code etc...
All is well
return $TempVariable
}
$TempVariable = Invoke-Command -ScriptBlock ${function:TempFunction} -ComputerName localhost
This all works fine.
The problem is that when I introduce a global array named InfoArray that stores information along the way and at the end wish to write it to a different server using other credentials it fails stating "Invoke-Command: The Using variable is not supported in the script function or filter"
Here is my introduced code:
#Append gathered log information to log
$strScriptUser = "domain\FileUser"
$strPass = "Password01"
$PSS = ConvertTo-SecureString $strPass -AsPlainText -Force
$cred = new-object system.management.automation.PSCredential $strScriptUser, $PSS
Start-Job -ScriptBlock { Add-Content $using:Logfile $using:InfoArray } -Credential $cred
return $TempVariable
}
Any ideas as to how I could solve this issue?
The following does not work
Start-Job -ScriptBlock { Add-Content $Logfile $InfoArray } -Credential $cred
Regards
Akr
Pass them as arguments to this script block, since it doesn't support using.
Sample
Start-Job -ScriptBlock {
param($logfile,$infoArray)
Add-Content $Logfile $InfoArray
} -Credential $cred -ArgumentList #($logfile,$infoArray)
I attempted to Invoke without using -computername localhost, which resulted in it working via a PS script.
The challenge was that I cannot load PowerCLi pssnapin as a 64 bit directly in system center orchestrator, and must invoke for it to work.
Finally, what seemed to work was running the function using the server name rather than localhost.
$TempVariable = Invoke-Command -ScriptBlock ${function:TempFunction} -computerName *ServerName*

How to avoid the crendetial dialog box while conecting to different system using powershell?

I am making connection to the diferent system using powershell. I want this process to be automated in a way that once user hits the powershell script he gets connected to different system without entering username and password details into the dialog box. So, currently my.PS1 script as follows:
Enable-PSRemoting -Force
Set-Item wsman:\localhost\client\trustedhosts CP0001256
Restart-Service WinRM
Test-WsMan CP0001256
$credential = Import-CliXml -Path "D:\$Env:USERNAME_pass.xml"
Invoke-Command -ComputerName CP0001256-ScriptBlock { Get-ChildItem D:\ }-credential $credential
Before running my.PS1 i have executed follwing script:
$credential = Get-Credential
$credential | Export-CliXml -Path "D:\$Env:USERNAME_pass.xml"
So, when i execute my.PS1 i got error as:
Invoke-Command : Cannot process argument transformation on parameter 'Credential'. username
At my.PS1:7 char 86
+ Invoke-Command -ComputerName CP0001256-ScriptBlock { Get-ChildItem D:\ } -credential <<<< $credential
+ CategoryInfo : InvalidData: (:) [Invoke-Command], ParameterBindin..mationException
+ FullyQualifiedErrorID : ParameterArgumentTransformationError,Microsoft.Powershell.Commands.InvokeCommand
So, tell me what i am doing wrong and how can i avoid getting the credential dialog box pop up appearing.
This is a question of how to store credentials in a script. Keep in mind that this always carries some risk. You can of course store them in plain text. Then anyone with access to the script has those credentials.
Another thing you can do is take advantage of the [PSCredential] object, and store the password encrypted. Consider running this code (outside of that script):
$credential = Get-Credential # dialog pops up here, enter server creds
$credential | Export-CliXml -Path "C:\Script\$Env:USERNAME_Credential.xml"
Now in your script, you can do this:
$credential = Import-CliXml -Path "C:\Script\$Env:USERNAME_Credential.xml"
Invoke-Command -ComputerName CP0001256-ScriptBlock { Get-ChildItem D:\ }-credential $credential
The password is encrypted within that XML file, and it's encrypted with a key that is specific to the user who ran the first set of commands, so only that user will be able to effectively run the script if you do this.
This is also why I use the USERNAME environment variable as part of the file name. You can have multiple employees run the first code snippet to generate a separate encrypted file for each of them. Then your script will work successfully when any of them run it.
It also works if you have an account used for a scheduled task for example; run the snippet as that user once, then the scheduled task will work.

Powershell : Accessing shared drive from remote server

I am trying to access shared drive vai remote server in my Powershell script. My code is below:
$bypass1 = "config"
$bypass2 = "web.config"
$Username = "test\newtest"
$Password = "xxxxxxxxx"
$srv = "xxx.xxx.xxx.xxx"
$securePassword = ConvertTo-SecureString -AsPlainText -Force $Password
$cred = New-Object System.Management.Automation.PSCredential $Username, $securePassword
$session = New-PSSession -ComputerName $srv -port 22 -Credential $cred
Invoke-Command -Session $session -ScriptBlock {
$computer = "xxx.xxx.xxx.xxx"
test-path \\$computer\netlog\php
Get-ChildItem \\$computer\netlog\
}
Remove-PSSession -Session $session
When I tried to access shared from Remote Desktop Connection on the server it is working but through powershell it is throwing following error.
False
Cannot find path '\\xxx.xxx.xxx.xxx\netlog\' because it does not exist.
+ CategoryInfo : ObjectNotFound: (\\xxx.xxx.xxx.xxx\netlog\:String) [Get-Ch
ildItem], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCom
mand
+ PSComputerName : xxx.xxx.xxx.xxx
I am having Powershell 4 and remote server is windows 2008 R2.
Regards,
Vj
Did you try accessing the following path \\xxx.xxx.xxx.xxx\netlog\ locally? You have the creds to access the server. And also you say the drive is shared. Try accessing the path locally. Not via power-shell. But try the old fashioned way. Using Run. If you are prompted for any credentials to be entered. You may strike off any issues related to permissions. If not... The folder you are trying to access isn't shared at all. Try giving it the required permissions. If this isn't the case please leave a comment.
You might need to enable Multihop Remoting when you access a share from a remote machine and use CredSSP.
The credentials you use to create the remote session are not passed to the share access action by default. I think everyone runs into this problem at least once. :)
http://blogs.technet.com/b/heyscriptingguy/archive/2013/04/04/enabling-multihop-remoting.aspx
http://blogs.technet.com/b/heyscriptingguy/archive/2012/11/14/enable-powershell-quot-second-hop-quot-functionality-with-credssp.aspx

Run ScriptBlock with different credentials

I have a script, that determines a userid; once I have that userid, I want to run a script block against that userid using different credentials. Is this possible? Can anyone show me examples of this?
I got it, thanks to Trevor Sullivan for pointing me in the right direction. I ended up just putting my second ps1 file into a scriptblock, and running it as a job, and passing it the arguments from the main script, like this
$job = Start-Job -scriptblock {
param ($username)
some code to run against the variable that was passed in
} -Args $target -credential $Cred
$target being the variable I want to pass to my scriptblock.
$username being the parameter that the scriptblock accepts Thanks.
I know this was answered a long time ago, but I thought I'd add another option for those looking that returns data without having to retrieve it.
We can create a helper script that creates a pscredential and then uses it to start a local PSSession to run a script or scriptblock in a different user's context. You need to get the user password from somewhere, preferably entered as a secure string or retrieved from a Key Vault, but for the example our helper script will take it as a string parameter.
Script contents:
param ([string]$username,[string]$password)
$Username = 'username#domain.com'
$Password = ConvertTo-SecureString -String $password -AsPlainText -Force
$Credential = New-Object -Type PSCredential($Username,$Password)
$Session = New-PSSession -Credential $Credential
Invoke-Command -Session $Session -FilePath C:\Path\to\some\script.ps1
You can also use -ScriptBlock instead of -FilePath if you have a simple chunk of code to run or you have converted a script to a script block.
Hope this helps somebody out!
Security context for a session is established when the session is initialized. You can't arbitrarily run commands under a different context within the session. To run under a different security context (set of credentials) you'll need to initialize a new session under those credentials and run it there.
If you look at the help for Invoke-Command, you'll note that the -Credential parameter is only valid in parameter sets that specify a remote session by computername, uri, or session. You can also use -credential with Start-Job, which will run the command in a new session on the local machine.
This code will launch PowerShell in Administrator mode using the credentials provided and then run the code in the script block. There might be others ways but this works for me.
$account= # AD account
$password = # AD user password
$passwordSecure = ConvertTo-SecureString ($password) -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential ($account, $passwordSecure)
$ScriptBlock = {
whoami
start-sleep 3
}
 
# Run PowerShell as Administrator with Custom Crednetails
start-Process powershell.exe -Credential $Cred -ArgumentList "-Command Start-Process powershell.exe -Verb Runas -ArgumentList '-Command $ScriptBlock'" -Wait

powershell credential rejected from server

I need to store credential in powershell to be used several times. Here on StackOverflow there are a lot of example, so I took one
$tmpCred = Get-Credential
$tmpCred.Password | ConvertFrom-SecureString | Set-Content "pwd.dat"
$password = Get-Content "pwd.dat" | ConvertTo-SecureString
$credential = New-Object System.Management.Automation.PsCredential "myDomain\myUser", $password
Get-ADUser -Credential $credential
Unfortunately I get this error and I can't find a solution
Get-ADUser : The server has rejected the client credentials.
At line:5 char:11
+ Get-ADUser <<<< "xxx" -Credential $credential
+ CategoryInfo : NotSpecified: (xxx:ADUser) [Get-ADUser], AuthenticationException
+ FullyQualifiedErrorId : The server has rejected the client credentials.,Microsoft.ActiveDirectory.Management.Commands.GetADUser
I can't see anything obviously wrong with your code, I'm guessing that this is just an example of how you are using it as you mention you need to use it in several places. Just to check that it really is the storing of the secure string failing you could check using the following, which should prove that the credentials worked before being persisted to disk:
Get-ADUser -Credential $tmpCred
One option would be to pass around the credentials rather than a file or securestring, using the type [System.Management.Automation.PSCredential] which is returned from your call to Get-Credentials and stored in the variable $tmpCred.
You could also temporarily add a call to the method GetNetworkCredentials() to ensure that your password has been decrypted correctly, the following will show the username and password (unencrypted):
$tmpCred.GetNetworkCredential().Username
$tmpCred.GetNetworkCredential().Password
Hope that helps...