Powershell functions and referencing the script that calls that function...

Lately I've been putting together functions so I can reuse code in my other scripts.  As part of error checking/reporting, I wanted to add a way for my function to reference the script that was making use of it.  I put a question out on twitter and here is what I learned.
Quick and Dirty:
function Test-Function
Write-Host "MyInvocation" -ForegroundColor:Green
[string]$test = $MyInvocation.ScriptName.split("\") | select -Last 1
Write-Host $test -ForegroundColor:Green

Hit page break if you want more details and an example of how I used $MyInvocation.

Problem Details:
Here is how it proves helpful to me:
I make scheduled task scripts that run on a scheduled basis.  These scripts tend to pull from several different data sources and 'do stuff' w/ that data.  Here is the problem:

  1. If one of my functions is unable to collect data from one source of 20, I still get data.
  2. What I don't get is one source, but I might be none the wiser unless my function checks for that condition.
  3. In order for my function to be useful, I need to know what script called it and notify me that it had problems connecting to that one data source.
My real-world example, I made a function to connect to all my vCenter's in one fell swoop.  In the example below, you'll see by calling $MyInvocation.ScriptName, I'm referencing the ps1 file that makes use of my function.  I then insert that into my subject and body of an e-mail should a failure occur.

This way, I receive an e-mail if one of my vCenter's fails to connect w/ information on which script started had the connection problem.

Here is a shortened version for simplicity sake (and yes, it is a 'shortened version'):

vCenter Server List
CSV Format: ServerName, DomainName, Location, Function
Function Connect-vCenters
  Connects to vCenter servers
  Utilizes a CSV input file located in \\myserver\input\vCenterList.csv
  Simply typing in Connect-vCenters will start a wizard prompting you for choices.
  Connect-vCenters -all
  Adding this switch will automatically connect to all vCenters in CSV file.  Can be used as part of automated scheduled tasks.
  Connect-vCenters -all -mailAlert:$true -mailto "example@blah.com"
  Connects to all vCenters and e-mail alerts on any connection failures to example@blah.com
  This is simply connect to all vCenters listed in the CSV file.
  Uses default location in module code unless otherwise specified.
  SMTP server used for e-mail alerts sent when vCenter connection fails
  vCenter connection failures sent to this address.  Default defined in function code.
  Sent from this address.  Default defined in function code.
  .PARAMETER MailAlert
  Defaults to false.  If set to true, will send an e-mail alert upon vCenter connection failure to mailto specified address.
# This tells me the script aka ps1 file that called this function for e-mail alerting.
$ScriptName=($MyInvocation.ScriptName.split("\") | select -Last 1)
$vCenterList = Import-Csv $CSVLocation
$Date = Get-Date
Switch ($all)
    Write-Host "Attempting to connect to the following servers:" -ForegroundColor:Green
    Write-Host "This was imported from: $($CSVLocation)"
        Foreach ($vCenter in $vCenterList)
            Write-Host "Connecting to $($vCenter.ServerName).$($vCenter.DomainName)" -ForegroundColor:Green
            Connect-VIServer ($vCenter.ServerName + "." + $vCenter.DomainName) | Out-Null
            If ($? -ne $true -and $mailalert -eq $true){Send-MailMessage -SmtpServer $SMTPServer -From $MailFrom -To $MailTo -Subject "$($ScriptName) error connecting to $($vCenter.ServerName).$($vCenter.DomainName)" -Body "$($ScriptName) run on $($date) was not able to successfully connect to $($vCenter.ServerName).$($vCenter.DomainName)"}

No comments: