I want to call another secondary powershell script from within my primary powershell script. I want to pass it a parameter from the primary script, the secondary script needs the username parameter, I want to pass to it, from the primary, and then have the secondary script Im calling use different credentials. I think I might be able to use invoke-command, I just dont know all the syntax, anyone able to post some examples of what I want to accomplish, and then I'll fill in the blanks if need be?
Thanks in advance! :-)
Assume that your secondary script looks like this:
param (
[string] $Username = $args[0]
)
Write-Output -InputObject $Username;
You can use the Start-Process cmdlet to launch the script with alternate credentials.
$Credential = Get-Credential;
Start-Process -Wait -NoNewWindow -FilePath powershell.exe -ArgumentList '"c:\path\to my\file.ps1" -Username "UsernameGoesHere!"' -Credential $Credential;
Or you can use the Invoke-Command cmdlet:
Invoke-Command -FilePath 'c:\path\to my\script.ps1' -Credential $Credential -ArgumentList "UsernameGoesHere!";
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.
Related
I recently started to learn Powershell. My problem is that I'm trying to run a powershell script to unfreeze a remote machine, but one of the parameters of Time Freeze contains a dollar sign. How do I do that?
Basically what I need to do is to run the following command:
cmd.exe /c "C:\Program Files\Toolwiz Time Freeze 2017\ToolwizTimeFreeze.exe" /unfreeze /usepass=$password
Where the dollar sign is part of the password.
If I run it on the powershell console directly on the remote machine, it works (I just have to add single quotes around $password). But when I try to run the script from my local machine, it gets stuck on it and I have to Ctrl C to cancel it.
The script in question is this:
$User = "user"
$PWord = ConvertTo-SecureString "password" -AsPlainText -Force
$Ip = Read-Host -Prompt 'Insira o IP da maquina de destino:'
$Cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $PWord
$sess = New-PSSession -Credential $Cred -ComputerName $Ip
Enter-PSSession $sess
Invoke-Command -ComputerName $Ip -ScriptBlock { cmd.exe /c "C:\Program Files\Toolwiz Time Freeze 2017\ToolwizTimeFreeze.exe" /unfreeze /usepass=$password} -Credential $Cred
Remove-PSSession $sess
Exit-PSSession
I tried using Start-Process -Filepath and & to run the Time Freeze but it doesn't work neither (the script is executed but nothing happens at all), but when I try to run other commands like creating a new folder on the remote machine or restarting it, it works perfectly.
I don't know what else to try.
Edit1: I tried to pass the parameter with the single quotes and I also
tried using -argumentlist, but it doesn't work neither.
Edit2: If I run the script locally, it works perfectly, even on the remote machine. But when I try to run it remotely it doesn't work. It seems very strange to me because I can run other commands remotely succesfully, but with this one I'm having troubles.
Edit3: I forgot to update the question here, but I solved it. The problem wasn't about the password after all. I discovered by chance that in my script I had to stop the TimeFreeze proccess before I could call it again, otherwise I'd got stuck on it. So that's how I solved it.
Have you tried escaping the $ in the password?:
/usepass="`$password"
No idea if this works, if not you could assign the password to a variable then provide that as an argument
$mypassword = "`$password"
If possible, try to wrap all of the arguments you're passing to cmd.exe up into a variable prior to calling Invoke-Command. Then you can pass the variable via -ArgumentList.
Here's a little example where i'm placing all my arguments into a $params variable and then passing it into the ScriptBllock of InvokeCommand. Note that you need to add the param() section at the top to accept your the variable you pass in via -ArgumentList.
$params = #("/c ipconfig /all")
Invoke-Command -ComputerName $Computer -Credential $Cred -ScriptBlock {
param(
$params
)
Write-Host "We passed in the following parameters: '$params'"
& "cmd.exe" $params
} -ArgumentList $params
If you are running this from PowerShell, you need to wrap quotes around values with spaces and escape the dollar sign in PowerShell and CMD.
$sb = { cmd.exe /c """C:\Program Files\Toolwiz Time Freeze 2017\ToolwizTimeFreeze.exe"" /unfreeze /usepass=\`$password"}
Invoke-Command -ComputerName $Ip -ScriptBlock $sb -Credential $Cred
so there's a lot of similar topics to this I've found, but I can't find anything that correlates with my issue.
invoke-command -computername $serverLocation -Credential $cred -filepath "C:\path\script2.ps1" -ArgumentList $configPath
I am calling a for a script that is stored on my local machine to run on another server. Everything works as intended except for passing the "configPath" variable. This is how I initiate the script -
. .\script1.ps1 -serverLocation 'serverNameHere' -username 'userNameHere' -configPath 'configPathHere'
It correctly grabs all the other parameters I pass into the first script. It just won't pass the configPath to the second script in the 'filepath'.
How can I get this parameter to pass through? Thanks so much.
In script2.ps1, you should define a param() block that accepts the parameter, and then you can refer to it by whatever name you give it. If you don't want to use a param() block then using $args[0] should work.
I simply want to be able to pass one parameter from one PS script to another, currently my script (script1) is as follows (all thanks to user CB):
$filepath = Resolve-Path "script2.ps1"
start-process -FilePath powershell.exe -ArgumentList "-file `"$($filepath.path)`""
This succesfully opens another script in via another powershell instance. Now i want to be able to carry across a parameter to the 'script2.ps1' script. I have tried the following but this doesnt not work:
script1.ps1
$name = read-host "The name"
$filepath = Resolve-Path "script2.ps1"
start-process -FilePath powershell.exe -ArgumentList "-file `"$($filepath.path)`"-name $name"
script2.ps1
Param(
[string]$name
)
write-host $name
This should simply pass over $name from script1 into $name in script2. I think im close but not quite close enough!
Thanks for any help!
The only problem I see is that you are missing a space after the last escaped ", try this:
start-process -FilePath powershell.exe -ArgumentList "-file `"$($filepath.path)`" -name $name"
Is there a specific reason why you want to run the second script in a separate instance of Powershell? If not, you would do much better just to run the script directly:
$name = read-host "The name"
.\script2.ps1 -name $name
This way you don't have to worry about escaping any of the parameters.
The way you were doing it forces all of the parameters to be converted to strings and processed by Windows command line processing. That can be a nightmare to ensure values get through in a usable form. If instead you just invoke the script directly you can pass objects as parameters and Powershell is all about using objects rather than strings.
I'm not very good with powershell (to be honest, I'm bad !) but I need to do a script which download pictures and store them in a specific shared folder. I can download the pictures easily, but the folder where I need to store them is protected and there's is only one user (created specifically) who has access on it.
So my question is : how can I configure my script to use this user credentials ? I searched on the net, but I can't understand. As I said, I'm not a powershell user, and I use OS X at home, so I'm not even good with Windows rights and permissions. So a clear and easy answer would be really appreciated !
Thank's !
Use the Invoke-Command command with the -Credential and -ScriptBlock parameters to launch a PowerShell ScriptBlock as a different account. I believe that you will also need to enable PSRemoting in order for Invoke-Command command to work, even on the local system.
$Credential = Get-Credential;
$ScriptBlock = { Copy-Item -Path c:\test\test.txt -Destination c:\test2\test.txt; };
Invoke-Command -Credential $Credential -ScriptBlock $ScriptBlock;
A more complicated solution would be to use the Start-Process cmdlet with the -Credential parameter, to kick off an external executable under an alternate credential. If you just want to kick off PowerShell code though, you're better off using Invoke-Command.
$Credential = Get-Credential;
$Executable = 'c:\path\to\file.exe';
Start-Process -FilePath $Executable -Credential $Credential -Wait -NoNewWindow;
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