Converting script into functions
A function is a reusable, callable code block(s). A function can accept parameters, and can produce different results based on values that are passed to it.
A typical anatomy of a PowerShell function looks like:
function Do-Something
{
<#
comment based help
#>
param
(
#parameters
)
#blocks of code
}To illustrate, let's create a
very simple function that takes a report server URL and lists all items in that report server. This function will take in a parameter for the report server URL, and another switch called $ReportsOnly, which can toggle displaying between all items, or only report items.
function Get-SSRSItems
{
<#
comment based help
#>
param
(
[Parameter(Position=0,Mandatory=$true)]
[alias("reportServer")]
[string]$ReportServerUri,
[switch]$ReportsOnly
)
Write-Verbose "Processing $($ReportServerUri) ..."
$proxy = New-WebServiceProxy `
-Uri $ReportServerUri `
-UseDefaultCredential
if ($ReportsOnly)
{
$proxy.ListChildren("/", $true) |
Where TypeName -eq "Report"
}
else
{
$proxy.ListChildren("/", $true)
}
}To call this
function, we can pass in the value for –ReportServerUri and also set the –ReportsOnly switch:
$server = "http://server1/ReportServer/ReportService2010.asmx"
Get-SSRSItems -ReportsOnly -ReportServerUri $server |
Select Path, TypeName |
Format-Table -AutoSize To allow your function to behave more like a cmdlet and work with the pipeline, we will need to add the [CmdletBinding()] attribute. We can also change the parameters to enable values to come from the pipeline by using ValueFromPipeline=$true. Inside the function definition, we will need to add three blocks:
BEGINPreprocessing; anything in this block will be executed once when the function is called.
PROCESSActual processing that is done for each item that is passed in the pipeline.
ENDPost-processing; this block will be executed once before the function terminates executing.
We will also need to specify in the parameter block that we want to accept input from the pipeline.
A revised function follows:
function Get-SSRSItems
{
<#
comment based help
#>
[CmdletBinding()]
param
(
[Parameter(Position=0,Mandatory=$true,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true)]
[alias("reportServer")]
[string]$ReportServerUri,
[switch]$ReportsOnly
)
BEGIN
{
}
PROCESS
{
Write-Verbose "Processing $($ReportServerUri) ..."
$proxy = New-WebServiceProxy `
-Uri $ReportServerUri -UseDefaultCredential
if ($ReportsOnly)
{
$proxy.ListChildren("/", $true) |
Where TypeName -eq "Report"
}
else
{
$proxy.ListChildren("/", $true)
}
}
END
{
Write-Verbose "Finished processing"
}
}To invoke, we
can pipe an array of servers to the
Get-SSRSItems function, and this automatically maps the servers to our –ReportServerUri parameter since we specified ValueFromPipeline=$true. Note that Get-SSRSItems will get invoked for each value in our array:
$servers = @("http://server1/ReportServer/ReportService2010.asmx", "http://server2/ReportServer/ReportService2010.asmx")
$servers |
Get-SSRSItems -Verbose -ReportsOnly |
Select Path, TypeName |
Format-Table -AutoSize