Powershell functions and referencing the script that calls that function...
Summary:
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.
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:
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.
@Zsoldier did you check this forum ? http://t.co/Rw3YN7texZ /cc @ScriptingGuys
— Johan Bijnens (@alzdba) April 15, 2014
Quick and Dirty:function Test-Function { Param ( [string]$Weird ) Write-Host "MyInvocation" -ForegroundColor:Green $MyInvocation [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:
- If one of my functions is unable to collect data from one source of 20, I still get data.
- What I don't get is one source, but I might be none the wiser unless my function checks for that condition.
- 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'):
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 { <# .SYNOPSIS Connects to vCenter servers .DESCRIPTION Utilizes a CSV input file located in \\myserver\input\vCenterList.csv .EXAMPLE Connect-vCenters Simply typing in Connect-vCenters will start a wizard prompting you for choices. .EXAMPLE Connect-vCenters -all Adding this switch will automatically connect to all vCenters in CSV file. Can be used as part of automated scheduled tasks. .EXAMPLE 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 .PARAMETER all This is simply connect to all vCenters listed in the CSV file. .PARAMETER CSVLocation Uses default location in module code unless otherwise specified. .PARAMETER SMTPServer SMTP server used for e-mail alerts sent when vCenter connection fails .PARAMETER MailTo vCenter connection failures sent to this address. Default defined in function code.
.PARAMETER MailFrom
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. #> param ( [switch]$all, [switch]$server, [string]$CSVLocation="\\myserver\input\vCenterList.csv", [string]$SMTPServer="my.smtpserver.local", [string]$MailTo="myemailaddress@prodigy.com", [string]$MailFrom="CompuServe@56kbaud.com", [boolean]$mailalert=$false ) # 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) { $true { Write-Host "Attempting to connect to the following servers:" -ForegroundColor:Green $vCenterList 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)"} } } $false {
}
Comments