Passing parameter using variable While generating DSC configuration - powershell

I am executing Powershell DSC script from Powershell. Below is the code snippet
Invoke-Command -ComputerName $public_ip_address -Credential $UserCredential -ScriptBlock {
param ($driveformat)
cd c:/provisioning
Install-PackageProvider -Name NuGet -Force -Scope CurrentUser
Install-Module -Name PSDscResources -Force
Install-Module -Name xStorage -Force
. .\DiskSetup.ps1
disksconfig -outputpath C:\DataDiskSetting -driveFormat $driveFormat
Start-DscConfiguration -Path C:\DataDiskSetting -Wait -Force -Verbose
} -ArgumentList ($driveformat)
While generating configuration I want to pass driveformat as variable "$driveFormat" instead of hardcoding like "NTFS". Somehow its not getting value of $driveformat any idea how we can solve this.

You can add a named Parameter $driveformat in your script. See below example:
Param([String]$driveformat)
Invoke-Command -ComputerName $public_ip_address -Credential $UserCredential -ScriptBlock {
param ($driveformat)
...
} -ArgumentList ($driveformat)
Then in the powershell task from pipeline, add -driveformat "NTFS" in the argument field. See below screenshot: (I defined a pipeline variable driveformat to hold the value "NTFS")
Or, you can add an Argument (eg. $driveformat = $args[0]) in your scripts. See below:
$driveformat = $args[0]
Invoke-Command -ComputerName $public_ip_address -Credential $UserCredential -ScriptBlock {
param ($driveformat)
...
} -ArgumentList ($driveformat)
Then you can directly pass the variable ("NTFS") in the Arguments field of powershell task:

Related

Remotely setting wallpaper on demand via powershell

I have created a function Set-Wallpaper:
Function Set-WallPaper($Value)
{
Set-ItemProperty -path 'HKCU:\Control Panel\Desktop\' -name wallpaper -value $value
rundll32.exe user32.dll, UpdatePerUserSystemParameters
}
and can run it locally to use a network path to the desired jpg
Set-Wallpaper -value "\\server\share\image.jpg"
and it works.
Now I want to run this function on a remote PC, I tried
Invoke-Command -ComputerName TARGETPC Set-Wallpaper -value "\\server\share\image.jpg"
but it errors out with
Invoke-Command : A parameter cannot be found that matches parameter name 'value'.
what am I missing?
$session= new-pssession -Computername "yourClientname"
$reslt= Invoke-Command -Session $session -ScriptBlock {your code}
If u want to ahnd over an argument use it like this
$reslt= Invoke-Command -Session $session -argumentlist $argument -ScriptBlock {param ($argument) your code with $argument[0]}

Set-Execution policy on remote computer using Variable

I have a problem reverting back powershell execution policy on remote computer using variable.
$RestrykcjaNowa = 'Bypass'
$RestrykcjaZastana = Invoke-Command -ComputerName $Komputer -ScriptBlock { Get-ExecutionPolicy }
$RestrykcjaZastana
Invoke-Command -ComputerName $Komputer -ScriptBlock { Set-ExecutionPolicy -ExecutionPolicy $RestrykcjaNowa -Scope LocalMachine -Force } | Out-Null
But I got an error
Cannot bind argument to parameter 'ExecutionPolicy' because it is null
When I replace variable $RestrykcjaNowa with value Bypass in last command it goes smoothly.
I noticed that variable $RestrykcjaZastana is not displayed on the screen when called in 2nd line of the code and is of type int but i can't assign value Bypass to integer variable manually.
What is wrong with my approach?
You have two issues to address:
Execution policies are not strings; they are a separate enumerated type, [Microsoft.PowerShell.ExecutionPolicy]. You will have to assign them as such to your variable:
$RestrykcjaNowa = [Microsoft.PowerShell.ExecutionPolicy]::Bypass
Variables outside of scriptblocks need to be referenced from within the script block with using::
Invoke-Command -ComputerName $Komputer -ScriptBlock { Set-ExecutionPolicy -ExecutionPolicy $using:RestrykcjaNowa -Scope LocalMachine -Force } | Out-Null
Variables are not evaluated when Scriptblock is defined.
However for your case, you may use below code with which you can pass variable to scriptblock as an argument:
$RestrykcjaNowa = 'Bypass'
$Komputer = '<Computername>'
$RestrykcjaZastana = Invoke-Command -ComputerName $Komputer -ScriptBlock { Get-ExecutionPolicy }
$RestrykcjaZastana
Invoke-Command -ComputerName $Komputer -ScriptBlock {param($RestrykcjaNowa) Set-ExecutionPolicy -ExecutionPolicy $RestrykcjaNowa -Scope LocalMachine -Force } -ArgumentList $RestrykcjaNowa | Out-Null

Calling param object inside script block

I am trying to create a folder remotely but the parameter that I type in command line doesn't pass in script block. Below code will only create directory webapp.
$computerName = "s3apdev0074"
Invoke-Command -ComputerName $computerName -ScriptBlock { param([string]$appname) md d:\webapp\$appname}
Please try this:
$ComputerName = 's3apdev0074'
$AppName = Read-Host "Please enter the application name"
Invoke-Command -ComputerName $ComputerName -ArgumentList $AppName -ScriptBlock {
Param (
[String]$AppName
)
# DOS:
md d:\webapp\$AppName
# PowerShell: New-Item -Path "d:\webapp\$AppName" -ItemType Directory
}
It seem you are only missing the -ArgumentList parameter to pass in your local variable.
More info here:
Get-Help Invoke-Command -Parameter ArgumentList

PSSession will not change the working directory

I have a script I'm trying to implement. If I run each line seperately, it works just fine. But if I place it in a function, or run with PowerGUI or Powershell ISE, it errors out. The problem is the script isn't changing the working directory, therefore the file that Invoke-Command is calling isn't found.
$DLUpdate = New-PSSession -ComputerName msmsgex10wprd03 -Credential $DLUpdateCred -Name DLUpdate
Enter-PSSession -Session $DLUpdate
$UpdateDLPath = 'c:\users\mascott2\Desktop\Distrolist\Updates\'
Set-Location $UpdateDLPath
Invoke-Command -ScriptBlock {cmd.exe "/c updatedls.bat"}
Exit-PSSession
Remove-PSSession -Name DLUpdate
You shouldn't be using Enter-PSSession in a script like that. Put all the commands you want into the scriptblock you use with Invoke-Command and run it against your session:
$DLUpdate = New-PSSession -ComputerName msmsgex10wprd03 -Credential $DLUpdateCred -Name DLUpdate
Invoke-Command -Session $DLUPdate -ScriptBlock {
$UpdateDLPath = 'c:\users\mascott2\Desktop\Distrolist\Updates\'
Set-Location $UpdateDLPath
cmd.exe "/c updatedls.bat"
}
Remove-PSSession -Name DLUpdate

Running Batch Script on remote Server via PowerShell

I need to connect to some remote servers from a client (same domain as the servers) once connected, I need to run a batch file:
I've done so with this code:
$Username = 'USER'
$Password = 'PASSWORD'
$pass = ConvertTo-SecureString -AsPlainText $Password -Force
$Cred = New-Object System.Management.Automation.PSCredential -ArgumentList $Username,$pass
try {
Invoke-Command -ComputerName "SERVER1" -Credential $Cred -ScriptBlock -ErrorAction Stop {
Start-Process "C:\Users\nithi.sundar\Desktop\Test.bat"
}
} catch {
Write-Host "error"
}
This script does not give any errors, but it doesn't seem to be executing the batch script.
any input on this would be greatly appreciated.
Try replacing
invoke-command -computername "SERVER1" -credential $Cred -ScriptBlock -ErrorAction stop { Start-Process "C:\Users\nithi.sundar\Desktop\Test.bat" }
with
Invoke-Command -ComputerName "Server1" -credential $cred -ErrorAction Stop -ScriptBlock {Invoke-Expression -Command:"cmd.exe /c 'C:\Users\nithi.sund
ar\Desktop\Test.bat'"}
It's not possible that the code you posted ran without errors, because you messed up the order of the argument to Invoke-Command. This:
Invoke-Command ... -ScriptBlock -ErrorAction Stop { ... }
should actually look like this:
Invoke-Command ... -ErrorAction Stop -ScriptBlock { ... }
Also, DO NOT use Invoke-Expression for this. It's practically always the wrong tool for whatever you need to accomplish. You also don't need Start-Process since PowerShell can run batch scripts directly:
Invoke-Command -ComputerName "SERVER1" -ScriptBlock {
C:\Users\nithi.sundar\Desktop\Test.bat
} -Credential $Cred -ErrorAction Stop
If the command is a string rather than a bare word you need to use the call operator, though:
Invoke-Command -ComputerName "SERVER1" -ScriptBlock {
& "C:\Users\nithi.sundar\Desktop\Test.bat"
} -Credential $Cred -ErrorAction Stop
You could also invoke the batch file with cmd.exe:
Invoke-Command -ComputerName "SERVER1" -ScriptBlock {
cmd /c "C:\Users\nithi.sundar\Desktop\Test.bat"
} -Credential $Cred -ErrorAction Stop
If for some reason you must use Start-Process you should add the parameters -NoNewWindow and -Wait.
Invoke-Command -ComputerName "SERVER1" -ScriptBlock {
Start-Process 'C:\Users\nithi.sundar\Desktop\Test.bat' -NoNewWindow -Wait
} -Credential $Cred -ErrorAction Stop
By default Start-Process runs the invoked process asynchronously (i.e. the call returns immediately) and in a separate window. That is most likely the reason why your code didn't work as intended.