1

I am trying to run a powershell script and have it output to my asp.net site. I have made it work with a very simple script where the only command in the script was

Get-Service | Out-String

and this output onto my site everything I expected

but when I use the script I actually want info from it doesn't output anything I can tell it runs (or trys to run) because when my site hits the code that invokes the script it hangs about 10 seconds.

The script I am trying to run is

$user = "user"
$token = "token"

$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))

$result = Invoke-WebRequest -Method Get -Uri 'https://site.vsrm.visualstudio.com/defaultcollection/product/_apis/release/releases?definitionId=1&api-version=3.0-preview.2&$expand=environments' -ContentType "application/json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}

$releaseArr = $result.Content | ConvertFrom-Json
[System.Collections.ArrayList]$enviromentName = @()
[System.Collections.ArrayList]$latestRelease = @()


foreach($env in $releaseArr.value[0].environments)
{
    $enviromentName.Add($env.name) | Out-Null
}


foreach($releaseValue in $releaseArr.value)
{
    For($i = 0; $i -lt $enviromentName.Count; $i++)
    {
        if($latestRelease[$i] -eq $null)
        {
            foreach($release in $releaseValue.environments)
            {
                if($release.name -eq $enviromentName[$i] -and $release.status -eq "succeeded")
                {
                    $latestRelease.Add($releaseValue.name) | Out-Null
                }
            }
        }
    }
}

For($i = 0; $i -lt $enviromentName.Count; $i++)
{
    Write-Host $enviromentName[$i] " : " $latestRelease[$i]
}

I know this script runs and outputs, but is there some code in this script that would cause it to not output properly.

The code in my asp.net site I am using to call the script is

ResultBox.Text = string.Empty;

        // Initialize PowerShell engine
        var shell = PowerShell.Create();

        // Add the script to the PowerShell object
        shell.Commands.AddScript(@"C:\Users\user\Desktop\script.ps1");

        // Execute the script
        var results = shell.Invoke();

        // display results, with BaseObject converted to string
        // Note : use |out-string for console-like output
        if (results.Count > 0)
        {
            // We use a string builder ton create our result text
            var builder = new StringBuilder();

            foreach (var psObject in results)
            {
                // Convert the Base Object to a string and append it to the string builder.
                // Add \r\n for line breaks
                builder.Append(psObject.BaseObject.ToString() + "\r\n");
            }

            // Encode the string in HTML (prevent security issue with 'dangerous' caracters like < >
            ResultBox.Text = Server.HtmlEncode(builder.ToString());
        }
3
  • 1
    Why are you using PowerShell to call the API from a website? You could just invoke the REST methods directly in your application. Commented Apr 7, 2017 at 17:19
  • we already have this script created and were looking for a way we could use the already existing script instead of recreating it Commented Apr 7, 2017 at 17:21
  • I recommend that you can consider this package nuget.org/packages/…, it is easy. Commented Apr 10, 2017 at 2:58

1 Answer 1

1

Change "Write-Host" to "Write-Output." Write-Host only outputs to interactive consoles.

You can see this in action:

Make a new PowerShell file and add a write-host statement to it:

[nick@nick-lt temp]$ New-Item -Type File -Path .\example.ps1 -Force
[nick@nick-lt temp]$ Set-Content .\example.ps1 "Write-Host 'Hello World'"

Then try and set a variable to the result of the script:

[nick@nick-lt temp]$ $what = .\example.ps1
Hello World
[nick@nick-lt temp]$ $what
[nick@nick-lt temp]$

Hello World shows up when the script executes but the variable is empty.

Now change it to write-output:

[nick@nick-lt temp]$ Set-Content .\example.ps1 "Write-Output 'Hello World'"
[nick@nick-lt temp]$ $what = .\example.ps1
[nick@nick-lt temp]$ $what
Hello World

The variable actually contains what it is supposed to now.

One of the cardinal rules of PowerShell is to not use Write-Host except in script that will be run interactively. .NET needs the results in the output stream not the host stream.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.