Do you know that we can convert a predominant parameter value into a true command? Yes, to test the connectivity of a server we usually use Test-Connection -ComputerName ServerName
, but how about using the ServerName -Ping
? I know what you are thinking, what if there are hundreds or thousands of servers, do we need to create those many functions? No, just only one function with the help of $MyInvocation
automatic variable.
$MyInvocation
is an automatic variable which contains information about the invocation details of the current execution, such as function or script name, parameters, parameter values, script root, script path, invocation name and etc., and $MyInvocation
works with scripts, functions, and script blocks only.
I will take the same ping example and show you that in action. I will write a small function to check the ping status with the name MyInvCmd and of course the name doesn’t matter and I will never use it or I can’t use it anywhere with that name, and here’s my function…
Function MyInvCmd
{
$ServerName = $MyInvocation.InvocationName
Test-Connection -TargetName $ServerName -IPv4 # In PowerShell 7
}
Now, if I load this function and call it in the console, then it will throw me an error like this…
But, as I said earlier I will never use this function with this name, so I will create an alias for this function with my server name. First to test this out in my local machine I will create an alias with localhost
name…
New-Alias -Name localhost -Value MyInvCmd
That’s all, now load the MyInvCmd function and call with the alias name localhost
in the console, and see the magic. You will see the ping results of the localhost
as below…
So, if you take a look at the function, $MyInvocation
returns the output as below and the value of the InvocationName
will be localhost
, the actual function name is MyInvCmd
though since it is being invoked by the alias name localhost
, the value of the InvocationName
is localhost
and assigned it to $ServerName
, and the same is used with -TargetName
parameter in the Test-Connection
cmdlet.
MyCommand : MyInvCmd
BoundParameters : {}
UnboundArguments : {}
ScriptLineNumber : 1
OffsetInLine : 1
HistoryId : 4
ScriptName :
Line : localhost
PositionMessage : At line:1 char:1
+ localhost
+ ~~~~~~~~~
PSScriptRoot :
PSCommandPath :
InvocationName : localhost
PipelineLength : 1
PipelinePosition : 1
ExpectingInput : False
CommandOrigin : Runspace
DisplayScriptPosition :
So, whatever the alias name that you create for MyInvCmd
will be used in the function as a server name, so what I will do is I will get the list of servers and create aliases with all of them.
$FilePath = "C:\Inventory\Servers.txt"
Get-Content -Path $FilePath | Foreach-Object { New-Alias -Name $_ -Value MyInvCmd }
Now, all the server names are aliases to MyInvCmd
but every alias invocation is unique and the function will work using the aliased server name.
This time I will add more functionality and parameters as well, so that we can change the behavior on every execution. Besides ping functionality, I will add the functionality to get the server info, enter into PSSession, RDP session, and still you can continue to add…
function MyInvCmd
{
<#
.SYNOPSIS
Replace MyInvCmd with the aliased server name
#>
[CmdLetBinding(DefaultParameterSetName = 'Help')]
param
(
[Parameter(Mandatory = $false)]
[switch] $Ping,
[Parameter(Mandatory = $false)]
[switch] $ServerInfo,
[Parameter(Mandatory = $false, ParameterSetName = 'PSSession')]
[switch] $PSSession,
[Parameter(Mandatory = $false, ParameterSetName = 'RDP')]
[switch] $RDP
)
$ServerName = $MyInvocation.InvocationName
if ($Ping) { Test-Connection -TargetName $ServerName -IPv4 } # In PS7
if ($ServerInfo)
{
$OSInfo = Get-CimInstance -ClassName CIM_OperatingSystem -ComputerName $ServerName
$CSInfo = Get-CimInstance -ClassName CIM_ComputerSystem -ComputerName $ServerName
[PSCustomObject]@{
OperatingSystem = $OSInfo.Caption
TotalMemory = $CSInfo.TotalPhysicalMemory
FreeMemory = $OSInfo.FreePhysicalMemory
NoOfCPUs = $CSInfo.NumberOfProcessors
NoOfLogicalCPUs = $CSInfo.NumberOfLogicalProcessors
LastRebootTime = $OSInfo.LastBootUpTime
}
}
if ($PSSession) { Enter-PSSession -ComputerName $ServerName }
if ($RDP) { Start-Process -FilePath mstsc.exe -ArgumentList /v:$ServerName }
if ($MyInvocation.BoundParameters.Count -eq 0) { Get-Help -Name $ServerName }
}
And now, I will get my list of servers and add them as aliases to this function. Since I am running this demo in my lab which is running in Hyper-V, I will get all the VM Names and add them as aliases…
Get-VM | ForEach-Object { New-Alias -Name $_.Name -Value MyInvCmd }
And here’s the list of aliases that I have created for MyInvCmd, and if you notice all the server names are pointing to the MyInvCmd
itself.
Now, let’s see how to use these aliases, you can use the server name as command and pass the parameters to it.
What I like the most in this concept is I can use this pretty much for anything, not only the servers but also I can convert my request numbers, incidents and etc., and you can add lot more functionality at your convince.