170

I'd like to restart a remote computer that belongs to a domain. I have an administrator account but I don't know how to use it from powershell.

I know that there is a Restart-Computer cmdlet and that I can pass credential but if my domain is for instance mydomain, my username is myuser and my password is mypassword what's the right syntax to use it?

I need to schedule the reboot so I don't have to type the password.

5
  • You should read this link Commented Jun 4, 2011 at 22:05
  • What does get-credential domain01\admin01 means? Next command is restart-computer -computername $s -force -throttlelimit 10 -credential $c. Does it mean that get-credential retrieve the password without asking it? Commented Jun 4, 2011 at 22:23
  • technet.microsoft.com/en-us/library/dd315327.aspx Commented Jun 4, 2011 at 22:34
  • There are several answers in this thread that do not require any prompt at all. The accepted answer is the top voted answer. If you accept one of the answers that do not require any prompt, you'll draw attention to the complete solution. The currently accepted answer will remain at the top. Commented Feb 1, 2024 at 22:20
  • RE: "schedule the reboot so I don't have to type the password" there are worlds of possibility in Task Scheduler, with or without powershell. There is a wealth of information on how to manage tasks in powershell here: sharepointdiary.com/2022/06/… Commented Aug 21, 2024 at 18:32

14 Answers 14

218

The problem with Get-Credential is that it will always prompt for a password. There is a way around this however but it involves storing the password as a secure string on the filesystem.

The following article explains how this works:

Using PSCredentials without a prompt

In summary, you create a file to store your password (as an encrypted string). The following line will prompt for a password then store it in c:\mysecurestring.txt as an encrypted string. You only need to do this once:

read-host -assecurestring | convertfrom-securestring | out-file C:\mysecurestring.txt 

Wherever you see a -Credential argument on a PowerShell command then it means you can pass a PSCredential. So in your case:

$username = "domain01\admin01" $password = Get-Content 'C:\mysecurestring.txt' | ConvertTo-SecureString $cred = new-object -typename System.Management.Automation.PSCredential ` -argumentlist $username, $password $serverNameOrIp = "192.168.1.1" Restart-Computer -ComputerName $serverNameOrIp ` -Authentication default ` -Credential $cred <any other parameters relevant to you> 

You may need a different -Authentication switch value because I don't know your environment.

Sign up to request clarification or add additional context in comments.

6 Comments

You can also do ConvertTo-SecureString "password" -AsPlainText -Force.
Just to make it clear, $password = ConvertTo-SecureString "password" -AsPlainText -Force
-Credential [username] was required in Read-Host parameters for me, otherwise powershell just hangs. After passing -Credential to read-host you will be prompted directly in powershell console and password is stored correctly. Thank You!
I am trying to figure out how to get this to work when I use the Send-MailMessage function in powershell. I am wanting to store the credentials of my email user and pass so I do not have to keep entering it in. Any idea how to do this?
@user3681591 - I'd recommend asking a new question rather than doing this in the comments. Thanks.
|
78

There is another way, but...

DO NOT DO THIS IF YOU DO NOT WANT YOUR PASSWORD IN THE SCRIPT FILE (It isn't a good idea to store passwords in scripts, but some of us just like to know how.)

Ok, that was the warning, here's the code:

$username = "John Doe" $password = "ABCDEF" $secstr = New-Object -TypeName System.Security.SecureString $password.ToCharArray() | ForEach-Object {$secstr.AppendChar($_)} $cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $secstr 

$cred will have the credentials from John Doe with the password "ABCDEF".

Alternative means to get the password ready for use:

$password = convertto-securestring -String "notverysecretpassword" -AsPlainText -Force 

6 Comments

Thanks. This is very helpful. In my case I was creating a custom powershell cmdlet that takes a user name and password (as secureString). Internally the cmdlet calls several other cmdlets, some need just a user and password but one of them needs a credential so I don't actually need to hard-code the password in my script.
Somewhat simpler: $password = convertto-securestring -String "notverysecretpassword" -AsPlainText -Force
I am trying to figure out how to get this to work when I use the Send-MailMessage function in powershell. I am wanting to store the credentials of my email user and pass so I do not have to keep entering it in. Any idea how to do this?
@user3681591 That would be Send-MailMessage -Credential $cred (with $cred created as shown in this post)
@JeroenLandheer I have tried your answer (thanks for helping!) however it did not work. My error is: -Credential : The term '-Credential' is not recognized as the name of a cmdlet, function, script file, or operable program.
|
33

Regarding storing credentials, I use two functions(that are normally in a module that is loaded from my profile):

#===================================================================== # Get-MyCredential #===================================================================== function Get-MyCredential { param( $CredPath, [switch]$Help ) $HelpText = @" Get-MyCredential Usage: Get-MyCredential -CredPath `$CredPath If a credential is stored in $CredPath, it will be used. If no credential is found, Export-Credential will start and offer to Store a credential at the location specified. "@ if($Help -or (!($CredPath))){write-host $Helptext; Break} if (!(Test-Path -Path $CredPath -PathType Leaf)) { Export-Credential (Get-Credential) $CredPath } $cred = Import-Clixml $CredPath $cred.Password = $cred.Password | ConvertTo-SecureString $Credential = New-Object System.Management.Automation.PsCredential($cred.UserName, $cred.Password) Return $Credential } 

And this one:

#===================================================================== # Export-Credential # Usage: Export-Credential $CredentialObject $FileToSaveTo #===================================================================== function Export-Credential($cred, $path) { $cred = $cred | Select-Object * $cred.password = $cred.Password | ConvertFrom-SecureString $cred | Export-Clixml $path } 

You use it like this:

$Credentials = Get-MyCredential (join-path ($PsScriptRoot) Syncred.xml) 

If the credential file doesnt exist, you will be prompted the first time, at that point it will store the credentials in an encrypted string inside an XML file. The second time you run that line, the xmlfile is there and will be opened automatically.

Comments

13

I have to run SCOM 2012 functions from a remote server that requires a different credential. I avoid clear-text passwords by passing the output of a password decryption function as input to ConvertTo-SecureString. For clarity, this is not shown here.

I like to strongly type my declarations. The type declaration for $strPass works correctly.

[object] $objCred = $null [string] $strUser = 'domain\userID' [System.Security.SecureString] $strPass = '' $strPass = ConvertTo-SecureString -String "password" -AsPlainText -Force $objCred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList ($strUser, $strPass) 

Comments

4

Here are two ways you could do this, if you are scheduling the reboot.

First you could create a task on one machine using credentials that have rights needed to connect and reboot another machine. This makes the scheduler responsible for securely storing the credentials. The reboot command (I'm a Powershell guy, but this is cleaner.) is:

SHUTDOWN /r /f /m \\ComputerName

The command line to create a scheduled task on the local machine, to remotely reboot another, would be:

SCHTASKS /Create /TN "Reboot Server" /TR "shutdown.exe /r /f /m \\ComputerName" /SC ONCE /ST 00:00 /SD "12/24/2012" /RU "domain\username" /RP "password"

I prefer the second way, where you use your current credentials to create a scheduled task that runs with the system account on a remote machine.

SCHTASKS /Create /TN "Reboot Server" /TR "shutdown.exe /r /f" /SC ONCE /ST 00:00 /SD "12/24/2012" /RU SYSTEM /S ComputerName

This also works through the GUI, just enter SYSTEM as the user name, leaving the password fields blank.

Comments

4

I saw one example that uses Import/Export-CLIXML.

These are my favorite commands for the issue you're trying to resolve. And the simplest way to use them is.

$passwordPath = './password.txt' if (-not (test-path $passwordPath)) { $cred = Get-Credential -Username domain\username -message 'Please login.' Export-CliXML -InputObject $cred -Path $passwordPath } $cred = Import-CliXML -path $passwordPath 

So if the file doesn't locally exist it will prompt for the credentials and store them. This will take a [pscredential] object without issue and will hide the credentials as a secure string.

Finally just use the credential like you normally do.

Restart-Computer -ComputerName ... -Credential $cred 

Note on Securty:

Securely store credentials on disk

When reading the Solution, you might at first be wary of storing a password on disk. While it is natural (and prudent) to be cautious of littering your hard drive with sensitive information, the Export-CliXml cmdlet encrypts credential objects using the Windows standard Data Protection API. This ensures that only your user account can properly decrypt its contents. Similarly, the ConvertFrom-SecureString cmdlet also encrypts the password you provide.

Edit: Just reread the original question. The above will work so long as you've initialized the [pscredential] to the hard disk. That is if you drop that in your script and run the script once it will create that file and then running the script unattended will be easy.

1 Comment

Nice. Can you correct a typo "Export-CliXML", the "xml" is missing.
2

Solution

$userName = 'test-domain\test-login' $password = 'test-password' $pwdSecureString = ConvertTo-SecureString -Force -AsPlainText $password $credential = New-Object -TypeName System.Management.Automation.PSCredential ` -ArgumentList $userName, $pwdSecureString 

For Build Machines
In the previous code replace user name and password values by secret ("hidden from logs") environment variables of your build-machine

Test results by

'# Results' $credential.GetNetworkCredential().Domain $credential.GetNetworkCredential().UserName $credential.GetNetworkCredential().Password 

and you'll see

# Results test-domain test-login test-password 

Comments

2

This is what I use and works for me.

$User="Domain\Username" $Password=[Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('VABlAHMAdABQAGEAcwBzAHcAbwByAGQA')) $SecurePassword = New-Object -TypeName System.Security.SecureString $Password.ToCharArray() | ForEach-Object {$SecurePassword.AppendChar($_)} $Credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $SecurePassword 

And to get VABlAHMAdABQAGEAcwBzAHcAbwByAGQA I do this:

To Encode $EString means Encrypted String and $DString means Decrypted String

$EString = Read-Host "Type Text to Encode" -AsSecureString $BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($EString) $DString=[System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) $Encoded=[Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($DString)) $Encoded # VABlAHMAdABQAGEAcwBzAHcAbwByAGQA $DString # TestPassword 

That way I can put any password I want on the script without too much hassle.

Comments

1
read-host -assecurestring | convertfrom-securestring | out-file C:\securestring.txt $pass = cat C:\securestring.txt | convertto-securestring $mycred = new-object -typename System.Management.Automation.PSCredential -argumentlist "test",$pass $mycred.GetNetworkCredential().Password 

Be very careful with storing passwords this way... it's not as secure as ...

Comments

1

Instead of storing the encrypted password in a text file you can store it in the credential vault. In the follwing example the user is prompted for a password only the first time, after that the password is retrieved from the credential vault.

# Load the Windows Runtime Class [Windows.Security.Credentials.PasswordVault,Windows.Security.Credentials,ContentType=WindowsRuntime] $Vault = New-Object Windows.Security.Credentials.PasswordVault $RESOURCE = "myresource" $USERNAME = "myuser" try { $credentials = $Vault.Retrieve($RESOURCE,$USERNAME) $pwd = $credentials.Password | ConvertTo-SecureString -Key (1..16) } catch { $pwd = Read-Host "please enter your password:" -AsSecureString $Encrypted = ConvertFrom-SecureString -SecureString $pwd -Key (1..16) $credentials = new-object -Type Windows.Security.Credentials.PasswordCredential -ArgumentList $RESOURCE,$USERNAME,$Encrypted $Vault.Add($credentials) } $cred = New-Object System.Management.Automation.PsCredential($USERNAME,$pwd) 

Comments

0

In case below code might help someone.

function Get-RemoteConnection() { //$serverIp can be passed as a parameter of the function. //I just make it static for testing. $serverIp = '192.168.100.137' Enable-PSRemoting -Force Set-Item wsman:\localhost\client\trustedhosts $serverIp Restart-Service WinRM #Set credentials needed for remote installation $userName = "administrator" $password = ConvertTo-SecureString "2020core0515" -AsPlainText -Force $cred = New-Object System.Management.Automation.PSCredential -ArgumentList ($userName, $password) $session = New-PSSession -ComputerName $serverIp -Credential $cred $a = Invoke-Command -Session $session -ScriptBlock { Get-WmiObject Win32_LogicalDisk -Filter "DriveType=3" | Select-Object DeviceID, @{label='UsedPercent'; expression={[Math]::Round((($_.size - $_.freespace) / $_.size) * 100, 2)}} } Write-Host $a return $session } function Delete-RemoteConnection($session) { Disconnect-PSSession $session | Out-Null Disable-WSManCredSSP -Role Client } 

Comments

0

You can create a secure string without a file on drive.

$username = "foo" $password = ConvertTo-SecureString -Force -AsPlainText "bar" 

And create a PSCredential as recommended by some of the other answers:

$cred = New-Object ` -TypeName System.Management.Automation.PSCredential ` -ArgumentList $username, $password 

Comments

0

Here is a simple one-liner:

New-Object System.Management.Automation.PSCredential -ArgumentList 'myuser', (ConvertTo-SecureString "mypassword" -AsPlainText -Force)

You can enclose it with parenthesis and supply it to a -Credential parameter. For example:

Invoke-WebRequest -Uri 'https://myhost.local' -Authentication Basic -Credential (New-Object System.Management.Automation.PSCredential -ArgumentList 'myuser', (ConvertTo-SecureString "mypassword" -AsPlainText -Force))

Comments

-3

why dont you try something very simple?

use psexec with command 'shutdown /r /f /t 0' and a PC list from CMD.

1 Comment

That's a specific case. The point is not spawning a login window in any random scenario.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.