Active IQ Unified Manager Discussions

WFA Invoke External PS scripts

Acrux
5,888 Views

So it seems simple to find some high level WFA talks and examples, but I can't seem to find anything where some detail or more complex tasks are discussed in the last few years. The few dar files that seem inline with my question which I have dug up won't import to 4.0 because they are so old.

 

I'm simply looking on how to setup a command that will invoke an external ps1 script with a var being passed to it.

 

Any examples or insight would greatly be appreciated.

 

Thanks

3 REPLIES 3

mbeattie
5,861 Views

Hi there,

 

Yes it's absolutely possible to have WFA call external powershell scripts and pass parameters to those scripts.

Here is a very basic example and framework that can be used to achieve that.

 

Create a directory structure within the WFA install directory. EG

 

  • mkdir <%wfa_install_path%>\Scripts
  • mkdir <%wfa_install_path%>\Scripts\PowerShell
  • mkdir <%wfa_install_path%>\Scripts\PowerShell\<%ScriptName%>

For example here is a simple script that will accept a hostname as an input parameter, attempt to ping that hostname and write the output to log file by date in the scripts directory:

Save the code below as:

 

<%wfa_install_path%>\Scripts\PowerShell\PingHostName\PingHostName.ps1

 

param(
   [Parameter(Mandatory=$True, HelpMessage="The hostname or IP address of the system to ping.")]
   [String]$HostName
)
#'------------------------------------------------------------------------------
#'Initialization Section.
#'------------------------------------------------------------------------------
[String]$scriptPath     = Split-Path($MyInvocation.MyCommand.Path)
[String]$scriptSpec     = $MyInvocation.MyCommand.Definition
[String]$scriptBaseName = (Get-Item $scriptSpec).BaseName
[String]$scriptName     = (Get-Item $scriptSpec).Name
[String]$isoDate        = Get-Date -uformat "%Y-%m-%d"
[String]$scriptLogSpec  = $scriptPath + "\" + $isoDate + ".log"
#'------------------------------------------------------------------------------
#'Ping the hostname and write the output to a file by date in the scripts directory.
#'------------------------------------------------------------------------------
ping $HostName | Out-File -FilePath $scriptLogSpec
#'------------------------------------------------------------------------------

Now create a WFA command as follows (I called the command "invoke_powershell_script"). EG

 

param(
   [Parameter(Mandatory=$True, HelpMessage="The hostname or IP address to pass as a parameter to the script.")]
   [String]$HostName,
   [Parameter(Mandatory=$True, HelpMessage="The name of the script to run within the '\Scripts\PowerShell\<scriptname>' folder in the WFA installation directory.")]
   [String]$ScriptName
)
#'---------------------------------------------------------------------------------
#'Read the WFA installation Path from the registry.
#'---------------------------------------------------------------------------------
[String]$registryPath = "hklm:\system\currentcontrolset\services\na_wfa_srv";
Try{
   [System.Object]$result  = Get-ItemProperty -Path $registryPath -ErrorAction Stop
   [String]$wfaPath        = $result.ImagePath.Split("/")[0].Trim() -Replace("""", "")
   Get-WFALogger -Info -Message "Read registry path ""$registryPath"""
}Catch{
   Get-WFALogger -Error -Message $("Failed Reading Registry Path ""$registryPath"". Error " + $_.Exception.Message)
   Throw "Failed Reading Registry Path ""$registryPath"""
}
#'---------------------------------------------------------------------------------
#'Check the format of the registry key value as it changes between WFA versions.
#'---------------------------------------------------------------------------------
#' <= WFA 3.0 = "C:\Program Files\NetApp\WFA/bin/NA_WFA_SRV.exe" //RS//NA_WFA_SRV
#' >= WFA 3.1 =  "C:\Program Files\NetApp\WFA\bin\NA_WFA_SRV.exe" //RS//NA_WFA_SRV
#'---------------------------------------------------------------------------------
If(($wfaPath.SubString($wfaPath.Length - 3, 3)) -eq "WFA"){
   [String]$installPath = $wfaPath
}Else{
   [String]$wfaBinPath  = $wfaPath.SubString(0, $wfaPath.LastIndexOf("\"))
   [String]$installPath = $wfaBinPath.SubString(0, $wfaBinPath.LastIndexOf("\"))
}
Get-WFALogger -Info -Message "Enumerated WFA installation Path from Registry key ""$registryPath"" as ""$installPath"""
#'---------------------------------------------------------------------------------
#'Ensure the script exists in the WFA install path.
#'---------------------------------------------------------------------------------
[String]$scriptFolder = $scriptName.Split(".")[0]
[String]$scriptSpec   = "$installPath\Scripts\PowerShell\$scriptFolder\$scriptName"
If(-Not(Test-Path -Path $scriptSpec)){
   Throw "The file ""$scriptSpec"" does not exist"
}
#'---------------------------------------------------------------------------------
#'Invoke the script in the WFA install path.
#'---------------------------------------------------------------------------------
[String]$command = "powershell.exe -ExecutionPolicy Bypass -File ""$scriptSpec"" -HostName $HostName"
Try{
   Invoke-Expression -Command $command -ErrorAction Stop
   Get-WFALogger -Info -Message "Executed command`: $command"
}Catch{
   Get-WFALogger -Error -Message $("Failed executing command`: $command. Error " + $_.Exception.Message)
   Throw "Failed executing command`: $command"
}
#'---------------------------------------------------------------------------------

Add the WFA command to a WFA workflow and execute it as follows.

Note: I used an an enum type for the "ScriptName" parameter so you can add other scripts into a list of scripts to run against the hostname. EG:

 

enum.png

 

When you run the run the workflow you enter a hostname and WFA will call the external powershell script and pass the hostname parameter to it. EG

 

execute_workflow.png

 

Then check the workflow logs to verify the execution status and note the highlighted command it ran:

 

workflow_execution.png

 

Then if you check the <%wfa_install_path%>\Scripts\PowerShell\<%ScriptName%> directory you will find a log file by date created by the external powershell script (called by WFA) containing the ping results for the hostname. EG:

 

<%wfa_install_path%>\Scripts\PowerShell\<%ScriptName%>dir /b
2016-09-27.log
PingHostName.ps1

<%wfa_install_path%>\Scripts\PowerShell\<%ScriptName%>type 2016-09-27.log

Pinging cluster1.testlab.local [192.168.100.2] with 32 bytes of data:
Reply from 192.168.100.2: bytes=32 time<1ms TTL=255
Reply from 192.168.100.2: bytes=32 time<1ms TTL=255
Reply from 192.168.100.2: bytes=32 time<1ms TTL=255
Reply from 192.168.100.2: bytes=32 time<1ms TTL=255

Ping statistics for 192.168.100.2:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 0ms, Maximum = 0ms, Average = 0ms

Whilst I realise this is a very "hello world" type of example the concept is meant to give you some ideas of the possibilities and provide a framework for using WFA to call external powershell scripts that you can expand on. Hope that helps?

 

/Matt

 

If this post resolved your issue, help others by selecting ACCEPT AS SOLUTION or adding a KUDO.

mbeattie
5,853 Views

Hi,

 

Also keep in mind that any external script that is called by WFA will be executed within the security context of the account that the WFA server services are running as (by default local system) which has no network access. Therefore if you want your external script to be able to interact with networked systems then consider using an Active Directory service account to run the WFA services as and ensure that this account is a local administrator account on your WFA server. EG:

 

wfa_services.png

 

Note: the WFA server services are configured to logon as an Active Directory user. The WFA AD service account is a member of the local administrators group

 

C:\>net localgroup administrators
Alias name     administrators
Comment        Administrators have complete and unrestricted access to the computer/domain

Members

-------------------------------------------------------------------------------
Administrator
TESTLAB\Domain Admins
TESTLAB\srv_netapp_wfa
The command completed successfully.

/Matt

If this post resolved your issue, help others by selecting ACCEPT AS SOLUTION or adding a KUDO.

abhit
5,846 Views

Hi Acrux:

 

Just wanted to know why you want to call a PS script from WFA and not execute

the PS script as a command in WFA.

 

There are plenty of workflows available at http://automationstore.netapp.com/home.shtml.

If you have already seen it, you can ignore.

 

Regards

Abhi

Public