Reputation: 505
I want to have in a .ps1 file some code that creates a PSSession that can be used in other .ps1 scripts (in order to avoid code duplication).
At first I thought i need a function that creates a PSSession and returns it but I am confused about how they the function outputs work.
Here is my function:
function newRemoteSession
{
param([string]$ipAddress)
$accountName = 'admin'
$accountPassword = 'admin'
$accountPasswordSecure = ConvertTo-SecureString $accountPassword -AsPlainText -Force
$accountCredential = New-Object System.Management.Automation.PSCredential ($accountName, $accountPasswordSecure)
Try
{
$remoteSession = New-PSSession -ComputerName $ipAddress -UseSSL -Credential $accountCredential -SessionOption (New-PSSessionOption -SkipCACheck -SkipCNCheck) -ErrorAction Stop
}
Catch [System.Management.Automation.RuntimeException] #PSRemotingTransportException
{
Write-Host 'Could not connect with default credentials. Please enter credentials...'
$remoteSession = New-PSSession -ComputerName $ipAddress -UseSSL -Credential (Get-Credential) -SessionOption (New-PSSessionOption -SkipCACheck -SkipCNCheck) -ErrorAction Stop
Break
}
return $remoteSession
}
However when I call $s = newRemoteSession(192.168.1.10)
, $s
is empty.
When I run a script with
Write-Host '00'
$s = newRemoteSession('192.168.1.10')
$s
Write-Host '02'
function newRemoteSession
{
........
Write-Host '01'
$remoteSession
}
I get only '00' in the console, but I know the function runs because I get the credential prompt.
EDIT:
Ok, now it works:
Upvotes: 2
Views: 80
Reputation: 438208
You've found the problems yourself, but since they're common pitfalls, let me elaborate a little:
Only ever use break
/ continue
inside a loop (for
, foreach
, while
, do
) or in the branch handlers of a switch
statement.
Otherwise, PowerShell looks up the call stack for an enclosing loop and, in the absence of one, exits the script.
This is what happened with the break
in your catch
block.
Do not use (...)
to enclose the list of function (command) arguments and do not separate arguments with ,
:
In PowerShell, functions - just like cmdlets - are called with shell-like syntax, without parentheses and with whitespace-separated arguments (,
is only used to construct an array to be passed as a single argument)[1]
.
# WRONG: method-invocation syntax does NOT apply to *functions*
# (It *happens* to work *in this case*, however, because only a
# a *single* argument is passed and the (...) is a no-op in this case,
# but this syntax should never be used.)
newRemoteSession('192.168.1.10')
# OK: Shell-like syntax, which PowerShell calls *argument mode*:
# Note that the argument needn't be quoted, because it
# contains no shell metacharacters.
# If there were additional arguments, you'd separate them with *whitespace*
newRemoteSession 192.168.1.10
# BETTER: You can even use *parameter names* (again, as with cmdlets),
# which helps readability.
newRemoteSession -ipAddress 192.168.1.10
In PowerShell, functions must be defined before you can call them.
newRemoteSession
function happened to exist.[1] For more information about PowerShell's two fundamental parsing modes - argument mode and expression mode - see this answer of mine.
Upvotes: 2