locked
Run .NET Script - Powershell V3.0 or above RRS feed

  • Question

  • Hi Community,

    I am currently implementing a Run .NET Script activity within a "create new user" runbook.

    The script (below) has been modified from a PowerShell form application that generates pass phrases using words taken from reddit/r/random. 

    I want to publish the $Password variable onto the data-bus which will then email the password to the user, but have run into problems.

    Orchestrator Run .NET PowerShell activities run in PowerShell 2.0. My script makes use of the Invoke-WebRequest cmdlet which was introduced in PowerShell 3.0. 

    Using the guide at http://karlprosser.com/coder/2012/04/16/calling-powershell-v3-from-orchestrator-2012/ I am able to run the script inside 3.0. I am having trouble returning the password string back to the data bus. The guide states that you can create a custom object to return data items (which i have done near the bottom of the script) and simply assign it to your published variable:

    $psresult = $psres.password

    This is not publishing the data to the databus, proved by appending the $psresult to a text file. 

    Does anybody have any experience of running PowerShell 3.0 script inside Orchestrator?

    Any help would be very gratefully received !

    $psres = Powershell{
    do{
    $Password = ""
    $Words =@()
    $UncommonWords =@()
    $Length = "2"
    $Output = "C:\PassPhraseScript\Pass.txt"
    $ScriptPath = "C:\PassPhraseScript"
    $Length = 0
    
    #Launch web request to collect 25x Post Titles from Reddit
    $URI = "http://www.reddit.com/r/random"
                
    #select the redirected .json page
    $Request = Invoke-WebRequest -Uri $uri -MaximumRedirection 0 -ErrorAction Ignore
    
    if($Request.StatusDescription -eq 'found'){
       $URI = $Request.Headers.Location}
    
    $URI = $URI.Substring(0,$URI.Length-1)
    $Redirect = $URI+".json"
    $URI = Invoke-WebRequest -Uri $Redirect
    $obj = ConvertFrom-Json ($URI.Content)
    $Data = $obj.Data.Children.Data | Select Title
            
    #Break down titles into words
    $Titles = $Data.title 
    $Words = $Titles.split(' ')
            
    #Filter out common redit text, special characters and numbers
    $RedditText = @("r/","u/")
    $Punctuation = @('"',"~","!","@","#","$","%","^","&","*","(",")","-","_","=","+","[","]","{","}","\","|",";",":","'",",","<",".",">","/","?")
    $Numbers = @("0","1","2","3","4","5","6","7","8","9")
    $Characters = $RedditText + $Punctuation + $Numbers
    foreach ($character in $Characters){
             $Words = $Words.Replace($character,"")}
            
    #Filter out small words and duplicates
    $Words = $Words | where-object {$_.length -ge 4}
    $Words = $Words | select -uniq
            
    #Filter out common words$ExcludedWordFile = "$ScriptPath\ExcludedCommonWords.txt"
           
    $ExcludedWords = Get-Content $ExcludedWordFile
    ForEach ($Word in $Words){
            if ($ExcludedWords -notContains $Word){
                    $UncommonWords += $Word}
                    }
    
    #Check for a decent sized Word pool and create Phrase out of uncommon words only
    $Count = $UncommonWords.count
    1..$Length | ForEach {$Password += ($UncommonWords | Get-Random)}      
    
    #Remove all remaining non a-z or A-Z characters and test length of final phrase
    $Password = [System.Text.RegularExpressions.Regex]::Replace($Password,"[^a-zA-Z]","");
    $Length = $Password.Length
    }While($length -gt 15)
    new-object pscustomobject -property @{
    password = $Password}
    }
    $psresult = $psres.password


    Monday, March 23, 2015 3:12 PM

Answers

  • Hi there, you can view this example runbook for the method I use to run PowerShell in a separate latest-version process and then return the results in a variable (open the "Execute Messaging Script" activity to view the script). This method uses Invoke-Command (line 34) to run the script content, and the resulting object ($ReturnArray) that comes back can then be published to the database. In this example, I return an array and then publish each part of the array as a separate value on the databus.

    Invoking:

    # Establish a new session (to localhost) to ensure 64bit PowerShell runtime $Session = New-PSSession -ComputerName localhost # Invoke-Command used to run the script contents in the new session $ReturnArray = @() $ReturnArray = Invoke-Command -Session $Session -Argumentlist $argsArray -ScriptBlock {

    ...

    Publishing result:

     ...

    return  @($ResultStatus, $ErrorMessage, $global:TraceLog)    }#End Invoke-Command Remove-PSSession $Session # Get properties from child session return $ResultStatus = $ReturnArray[0] $ErrorMessage = $ReturnArray[1] $Trace += $ReturnArray[2]

    You can find more documentation of the method starting on pg 61 of this ebook. Let me know if that makes sense.


    Noah Stahl | Automys | Downloadable Microsoft automation examples and solutions


    • Edited by Noah Stahl Monday, March 23, 2015 5:22 PM typo
    • Proposed as answer by Noah Stahl Monday, March 23, 2015 5:23 PM
    • Marked as answer by demonsblood Wednesday, March 25, 2015 2:36 PM
    Monday, March 23, 2015 5:21 PM

All replies

  • Hi there, you can view this example runbook for the method I use to run PowerShell in a separate latest-version process and then return the results in a variable (open the "Execute Messaging Script" activity to view the script). This method uses Invoke-Command (line 34) to run the script content, and the resulting object ($ReturnArray) that comes back can then be published to the database. In this example, I return an array and then publish each part of the array as a separate value on the databus.

    Invoking:

    # Establish a new session (to localhost) to ensure 64bit PowerShell runtime $Session = New-PSSession -ComputerName localhost # Invoke-Command used to run the script contents in the new session $ReturnArray = @() $ReturnArray = Invoke-Command -Session $Session -Argumentlist $argsArray -ScriptBlock {

    ...

    Publishing result:

     ...

    return  @($ResultStatus, $ErrorMessage, $global:TraceLog)    }#End Invoke-Command Remove-PSSession $Session # Get properties from child session return $ResultStatus = $ReturnArray[0] $ErrorMessage = $ReturnArray[1] $Trace += $ReturnArray[2]

    You can find more documentation of the method starting on pg 61 of this ebook. Let me know if that makes sense.


    Noah Stahl | Automys | Downloadable Microsoft automation examples and solutions


    • Edited by Noah Stahl Monday, March 23, 2015 5:22 PM typo
    • Proposed as answer by Noah Stahl Monday, March 23, 2015 5:23 PM
    • Marked as answer by demonsblood Wednesday, March 25, 2015 2:36 PM
    Monday, March 23, 2015 5:21 PM
  • Thanks Stefan for pointing that method out. I would caution against it though, and added this comment to the original blog post:

    This method appears to be explicitly discouraged by Microsoft, and doesn't seem wise in light of the fact that there are fully-tested ways to invoke a new session with latest PS version from Orchestrator's Run .Net Script activity. So, be careful. :)

    See: https://connect.microsoft.com/PowerShell/feedback/details/525435/net-4-0-assemblies-and-powershell-v2

    "While it is possible to force PowerShell 2.0 to run with .NET Framework 4.0 using various mechanisms such as creating a config file for PowerShell or editing the registry, these mechanisms aren't supported and can have negative side effects on other PowerShell functionality such as PowerShell remoting and cmdlets with mixed-mode assemblies."


    Noah Stahl | Automys | Downloadable Microsoft automation examples and solutions

    Monday, March 23, 2015 5:49 PM
  • Hi Noah,

    thanks. Of course, setting this key may (!) effect installed IPs or other ustom "Run .Net Script" activities.

    I added this hint in my post.

    Regards,

    Stefan


    www.sc-orchestrator.eu , Blog sc-orchestrator.eu


    Tuesday, March 24, 2015 7:31 AM
    Answerer
  • For anyone looking for a template runbook that uses the best practice I've found for running PowerShell in Orchestrator, I created a resource with a downloadable runbook and script that can be reused. This method has worked well for me, hope it helps. Link:

    PowerShell & System Center Orchestrator - Best Practice Template


    Noah Stahl | Automys | Downloadable Microsoft automation examples and solutions


    • Edited by Noah Stahl Wednesday, March 25, 2015 2:41 PM typo
    Wednesday, March 25, 2015 2:35 PM
  • Thankyou for this Noah - worked like a charm !

    Saved the day :)

    Wednesday, March 25, 2015 2:36 PM
    • Edited by Noah Stahl Wednesday, March 25, 2015 2:42 PM typo
    Wednesday, March 25, 2015 2:42 PM