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
There are a few things which need to be changed in order for this script to work.
run_commend_on_remote_server
function, you're using Enter-PSSession
which is meant for interactive sessions, and then you're using Invoke-Command
, in this case if I understand your intent correctly Enter-PSSession
has to be removed.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 the Invoke-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.
&
or the dot sourcing operator .
to invoke it, i.e.: & $choosen_function
.UserName
and Password
as argument of your script, I would personally recommend you to call Get-Credential
inside your script.-absolute_path
is being used as parameter for run_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