Jenkins won't run Start-Job with Credential parameter - windows

I pass in credentials to the script via the env injector (note this works for me with Invoke-Command) and try to run Start-Job but jenkins doesn't like it:
$user = $ENV:user
$pass = $ENV:pass
write-output (cat env:username)
write-output (cat env:user)
write-output (cat env:pass)
$pass = $pass | ConvertTo-SecureString -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList ($user), $pass
Start-Job -Credential $cred -ScriptBlock {'test'}
write-output (get-job | Receive-Job)
get-job | remove-job
This is the error I get (confirmed username and password are correct, when I run this script from the console with the same creds it works)
Started by user ME
[EnvInject] - Loading node environment variables.
Building in workspace C:\Program Files (x86)\Jenkins\jobs\myjob\workspace
[workspace] $ powershell.exe -NonInteractive -ExecutionPolicy ByPass "& 'C:\Windows\TEMP\hudson1723222179976241861.ps1'"
MYJENKINSSRV$
correctdomain\correctuser
correctPassword
Id Name PSJobTypeName State HasMoreData Location
-- ---- ------------- ----- ----------- --------
1 Job1 BackgroundJob Failed False localhost
[localhost] An error occurred while starting the background process. Error
reported: Access is denied.
+ CategoryInfo : OpenError: (localhost:String) [], PSRemotingTran
sportException
+ FullyQualifiedErrorId : -2147467259,PSSessionStateBroken
Finished: SUCCESS

i've had issues with credentials at times with PowerShell, i can usually fix it by using this:
$username = Username
$password = Password
$cred = New-Object -TypeName System.Management.Automation.PSCredential ($username, $password)
$Credentials = Get-Credential $cred
Basically entering the credentials into Get-credentials, then using that for credentials.

Related

Powershell: Passing Credentials in a PSSession to a machine returns Incorrect network password

Just some notes:
The issue that is being faced does not happen on every machine, only 1 in 20
I know it is not a powershell issue, but need to know from a health perspective what could cause this
The machine allows a connection with an Admin account over the PS Port, but after that the machine does not see the rights of the account
If I pass the Credentials using a Get-Credential rather than a PS Credential Object, it works however this is not an acceptable solution as the script it being wrapped in an MSO Runbook
Code being used for Credentials:
$Username = "domainname\userid"
$Password = "P#s4w0rd1!" | ConvertTo-SecureString -AsPlainText -Force
$mycreds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Username, $Password
Code for the PSSession:
$Session1 = New-PSSession -ComputerName WorkstationNAme #Connects to the computer
Invoke-Command -Session $Session1 -ScriptBlock {
$FreeDrive = (68..90 | %{$L=[char]$_; if ((gdr).Name -notContains $L) {$L}})[0] #Grabs the first available Drive Letter
$execDriveLocation = New-PSDrive -Name $FreeDrive -PSProvider FileSystem -Root $Using:Variable1 -Credential $using:mycreds -Persist #Creates temporary mapped drive
}
Error Returned on the affected machines:
The specified network password is not correct
+ CategoryInfo : InvalidOperation: (D:PSDriveInfo) [New-PSDrive], Win32Exception
+ FullyQualifiedErrorId : CouldNotMapNetworkDrive,Microsoft.PowerShell.Commands.NewPSDriveCommand
+ PSComputerName : computername
Any thoughts or suggestions?

Powershell -NoNewWindow not working as expected

Basically I want to switch user in powershell in the same window (dont want to open a new one).
$username = "xxxxx"
$password = ConvertTo-SecureString "xxxxx" -AsPlainText -Force
$creds = New-Objet System.Management.Automation.PSCredential $username,$password
Start-Process powershell.exe -NoNewWindow -Credential $creds
But instead of launching powershell in same window it launches it in a new window which doesnt even work I cant type anything into its just a blinking cursor.
First things first, try to describe what you need to do in detail since the approach you're using might be misguided. Are you just trying to run commands as a different user within a script? If so, use the methods described here : https://www.itdroplets.com/run-a-command-as-a-different-user-in-powershell/
I particularly like the start-job method which I use sometimes, example:
#Shows who is the current user
whoami
""
$username = "DOMAIN\USER"
$password = ConvertTo-SecureString "PASSWORD" -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential $username,$password
$GetProcessJob = Start-Job -ScriptBlock {
#Shows who is the current user, in this case it's the user you provided credentials for. Everything in this scriptblock will run in his context.
whoami
} -Credential $Credential
#Wait until the job is completed
Wait-Job $GetProcessJob | Out-Null
#Get the Job results
$GetProcessResult = Receive-Job -Job $GetProcessJob
#Print the Job results
$GetProcessResult
If you truly just want to just launch another powershell.exe process as another user,
the only way I know of would be to simply start the new process and exit the first one after that command, this way you have only the new window running as the user provided.
$username = "DOMAIN\USER"
$password = ConvertTo-SecureString "PASSWORD" -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential $username,$password
Start-Process powershell.exe -Credential $creds ;Exit

Why my powershell script return wrong exit code?

I'm trying to return exit code from a powershell script that is executed on a remote machine. But, when I check ExitCode it has some random number.
What I'm doing wrong? In addition, is it possible to return the whole text?
my script
$proc = Start-Process -Filepath "$PSExec" -ArgumentList "\\$server -h -u $user -p $pass -d PowerShell $command" -PassThru -Wait
$proc.ExitCode
remote script
New-Item "c:\temp\1.txt" -type file -force
exit 123
UPDATE
$secureString = ConvertTo-SecureString $password -Force -AsPlainText #$password includes password in clear text
$cred = New-Object System.Management.Automation.PSCredential($usrName, $secureString)
$sess = New-PSSession -ComputerName $serverName -Credential $cred
$command = "`"C:\temp\1.ps1`""
$result = Invoke-Command -Session $sess -ScriptBlock {
Start-Process -Filepath "$PSExec" -ArgumentList "\\$server -h -u $usrName -p $password -d PowerShell $command" -PassThru -Wait
}
Can you use Invoke-Command as an alternative?
Example:
$session = New-PSSesson -ComputerName $serverName -Credential (Get-Credential)
$result = Invoke-Command -Session $session -ScriptBlock {
Start-Process ...
}
As an alternative to Get-Credential you can created a credential object and pass it via the -Credential paramter to Invoke-Command. Example:
$secureString = ConvertTo-SecureString $password -Force -AsPlainText #$password includes password in clear text
$cred = [System.Management.Automation.PSCredential]::new($usrName, $secureString)
$sess = New-PSSession -ComputerName $ComputerName -Credential $cred
Invoke-Command -Session $sess -ScriptBlock { ... }
$result should also include the ExitCode property, since Powershell Remoting serializes the remote object. I always suggest Powershell Remoting compared to the cmdlet specific ComputerName implementations. It uses a more standardized way (WsMan -> HTTP(S)). See this link for further details.
Hope that helps.
For your first approach, your issue is that when running psexec with the -d (don't wait) flag it returns the pid of the command that launched it, rather than waiting and returning the exitcode.
Altogether your process also could be optimized. First if you wanted to use psexec.exe, I don't see a reason for Start-Process since you are waiting and passing through. Just & $psexec ... would suffice.
However Moerwald's suggestion for using Invoke-Command is a great one. In your updated code, you are still running Start-Process and Psexec which are unnecessary. When you are invoking the command, you are already remotely running code, so just run the code:
$secureString = ConvertTo-SecureString $password -Force -AsPlainText
$cred = New-Object System.Management.Automation.PSCredential($usrName, $secureString)
$result = Invoke-Command -ComputerName $serverName -Credential $cred -ScriptBlock {
New-Item "c:\temp\1.txt" -type file -force
exit 123
}
Also, since it doesn't look like you are reusing the session, I dropped the saving the session to a variable. And it would also be better to replace all of the credential setup with a Get-Credential rather than passing plaintext passwords around (avoid the password ending up in a saved transcript). That would look like this:
$result = Invoke-Command -ComputerName $serverName -Credential (Get-Credential) -ScriptBlock {
New-Item "c:\temp\1.txt" -type file -force
exit 123
}

Powershell get-credentials fails

PS C:\Windows\system32> $creds = Get-Credential
cmdlet Get-Credential at command pipeline position 1 Supply values for
the following parameters: Credential
PS C:\Windows\system32> $ses = New-PSSession -ComputerName WIN-O4VC136J0E2 -Credential $creds
New-PSSession : [WIN-O4VC136J0E2] Connecting to remote server
WIN-O4VC136J0E2 failed with the following error message : The user
name or password is incorrect. For more information, see the
about_Remote_Troubleshooting Help topic. At line:1 char:8
+ $ses = New-PSSession -ComputerName WIN-O4VC136J0E2 -Credential $creds
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OpenError: (System.Manageme....RemoteRunspace:RemoteRunspace) [New-PSSession],
PSRemotin gTransportException
+ FullyQualifiedErrorId : LogonFailure,PSSessionOpenFailed
The credentials I used are the same ones I used to login manually. Is there something else I am doing wrong? I've tried several different ways and never can seem to login.
Try the following, works very nicely with either a domain account or local account:
# Enter your pass and stores it securely:
$SecureString = Read-Host -AsSecureString 'Enter your password ' | ConvertFrom-SecureString | ConvertTo-SecureString
# Users you password securly
$MySecureCreds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "MyLoCalMachine\MyUserID",$SecureString
# Sets yous credentials to be used
$RemoteConn = New-PSSession -ComputerName $ts -Credential $MySecureCreds -Authentication default

Moving client to a workgroup when the domain machine account doesn't exist

I'm working on some automation in our test environment where we have powershell scripts to join a windows client to either a domain or a workgroup.
I'm having trouble trying to move a windows 7 client from a domain to a workgroup, in the case where the client's machine account doesn't exist in the domain.
Here is the code:
$User = administrator
$Password = ConvertTo-SecureString "<password>" -AsPlainText -Force
$DomainCred = New-Object System.Management.Automation.PSCredential $User, $Password
remove-computer -credential $DomainCred -force -passthru -verbose
This is the error that is returned:
VERBOSE: Performing operation "Remove-Computer" on Target "localhost".
Remove-Computer: This command cannot be executed on target computer ('xxx')
due to following error: No mapping between account names and security IDs was done.
At line :1 char:16
+ remove-computer <<<< -credential $DomainCred -force -passthru -verbose
+ CategoryInfo : InvalidOperation: (xxx:String) [Remove-Computer],
InvalidOperationException
+ FullyQualifiedErrorId : InvalidOperationException,Microsoft.Powershell.
Commands.RemoveComputerCommand
However, if I try this using the GUI (Computer Properties, Advanced system settings, Computer Name , Change...), it prompts for credentials and succeeds.
How would I replicate this operation into the powershell command so that it can be done pragmatically?
Try Add-Computer, like this (untested):
Add-Computer -WorkgroupName "WORKGROUP" -Force
AFAIK the only difference between Add-Computer and Remove-Computer is that Remove-Computer also disables the computer account, which would probably give you this error since the computer account doesn't exist.
I have two options.
Option 01
$Workgroup = "CL-01" #IF you want to add computer to domain edit here(Domain name)
$Password = "Password" | ConvertTo-SecureString -asPlainText -Force
$Username = "$Workgroup\Username"
$Credential = New-Object System.Management.Automation.PSCredential($Username,$Password)
Add-Computer -WorkGroup $Workgroup -Credential $credential
Restart-Computer -Force
Option 2 and why Option 2 Storing a password in a script is not such a favorable option so I suggest taking up option 2
$Workgroup = "CL-01"#IF you want to add computer to domain edit here(Domain name)
$Password = Read-Host -Prompt "Enter password for $user" -AsSecureString
$Username = "$Workgroup\Username"
$credential = New-Object System.Management.Automation.PSCredential($Username,$Password)
Add-Computer -WorkGroup $Workgroup -Credential $credential
Restart-Computer -Force
Note: Run the all the Scripts as Administrator!!
Hope this will help!! Cheers!!

Resources