I have two server one of them is Active directory and other is Windows10. I want to write a Powershell script that delete and make a directory.(for easy situation I choose delete and make directory but in real, The script used for getting group and organization unit of active directory.)
I write three function and below Powershell script. the first one is for run command on remote server and two of them for create and delete a directory. The my_powershell_script.ps1
Param($choosen_function, $username, $password, $remote_address, $absolute_path)
function run_commend_on_remote_server {
param ($choosen_function, $username, $password, $remote_address)
$secpsw = $password | ConvertTo-SecureString -AsPlainText -Force
$credobject = New-Object System.Management.Automation.PSCredential -ArgumentList $UserName, $secpsw
$psrs = New-PSSession -Credential $credobject -ComputerName $remote_address
Enter-PSSession $psrs
Invoke-Command -ScriptBlock {$choosen_function -absolute_path $absolute_path} -Session $psrs
Exit-PSSession
Remove-PSSession $psrs
}
function delete_directory{
param($absolute_path)
Remove-Item $absolute_path -Recurse
}
function make_directory{
param($absolute_path)
mkdir $absolute_path
}
run_commend_on_remote_server -choosen_function $choosen_function -username $username -password $password -remote_address $remote_address -absolute_path $absolute_path
When I run this script as below I got errors:
my_powershell_script.ps1 -choosen_function make_directory -username admin -password admin -remote_address 192.168.2.22
CodePudding user response:
There are a few things which need to be changed in order for this script to work.
- On your
run_commend_on_remote_server
function, you're usingEnter-PSSession
which is meant for interactive sessions, and then you're usingInvoke-Command
, in this case if I understand your intent correctlyEnter-PSSession
has to be removed. - On the same function, inside
Invoke-Command
script blocks's,$choosen_function
is being used however the 2 helper functions have not been defined on that scope (remote scope). You need to pass the definition of your functions if you want to use them remotely. Same thing applies for$absolute_path
. In order to pass locally defined variables into the remote scope, you can use either-ArgumentList
or$using:
, see Example 9 from theInvoke-Command
Doc.
The command uses the
Using
scope modifier to identify a local variable in a remote command. By default, all variables are assumed to be defined in the remote session. TheUsing
scope modifier was introduced in PowerShell 3.0.
- Since the name of the helper function you want to run is stored in a variable, in order to execute it, you would need to use the call operator
&
or the dot sourcing operator.
to invoke it, i.e.:& $choosen_function
. - Instead of passing
UserName
andPassword
as argument of your script, I would personally recommend you to callGet-Credential
inside your script. -absolute_path
is being used as parameter forrun_commend_on_remote_server
but the function does not have such parameter.
With these points being understood, here is how you could approach your script:
[cmdletbinding()]
param(
[ValidateSet('delete_directory', 'make_directory')]
$choosen_function,
$remote_address,
$absolute_path
)
function delete_directory{
# code here
}
function make_directory{
# code here
}
# store both function's definition, this will be used
# to pass them to the remote scope
$def = @(
${function:delete_directory}.ToString()
${function:make_directory}.ToString()
)
function run_commend_on_remote_server {
param ($choosen_function, $remote_address, $Credential, $absolute_path)
Invoke-Command -ScriptBlock {
# bring the definition of both functions to this scope
$deldir, $makedir = $using:def
# define both functions
${function:delete_directory} = $deldir
${function:make_directory} = $makedir
# invoke the chosen function
& $using:choosen_function -absolute_path $using:absolute_path
} -Credential $Credential -ComputerName $remote_address
}
# Here we call Get-Credential to get the pop-up for username and secure password
$cred = Get-Credential
$params = @{
choosen_function = $choosen_function
credential = $cred
remote_address = $remote_address
absolute_path = $absolute_path
}
run_commend_on_remote_server @params