Weird Return Value

This topic contains 2 replies, has 2 voices, and was last updated by Profile photo of Kawika Moss Kawika Moss 1 year, 9 months ago.

  • Author
    Posts
  • #22965
    Profile photo of Kawika Moss
    Kawika Moss
    Participant

    I've created 2 functions to use within a series of functions that automate a pretty lengthy process. My issue is I'm getting a weird return when I try to get the return value as a string variable.

    [b]This first function tests whether the app can be connected to by creating a cmd prompt batch file and running it, then capturing a log, this works as expected.[/b]
    [hr]
    function Get-LicenseStatus {

    [CmdletBinding()]
    param
    (
    [Parameter(Mandatory=$true)] [string]$ServerName
    )

    $QueryText = @"
    @REM File to be deleted
    SET FileToDelete="D:\TestLogs\APP\APPLicenseTest.log"

    IF EXIST %FileToDelete% del /F %FileToDelete%

    "C:\Program Files\APP\APP 5\APP_console.exe" -licencesourcelocation $ServerName`:27443 -licenceworkers 6 -licencesourcetype server -licencetype enterprise-workstation D:\TestScript\Test.rb

    IF %ERRORLEVEL% EQU 0 (Echo OK> %FileToDelete%) ELSE (echo NoLicense> %FileToDelete%)
    "@

    Set-Content D:\TestScript\APP\APPLicenseTest.bat $QueryText -Encoding Ascii
    [void](cmd.exe "/c D:\TestScript\APP\APPLicenseTest.bat")
    $LicenseStatus = Get-Content D:\TestLogs\APP\APPLicenseTest.log
    Write-Verbose -Message "License Status: $LicenseStatus"

    return $LicenseStatus

    }
    [hr]

    [b]This second script is where the issue is, the return value shows fine when this is run, but if you write-host for it or call the function in antoher script and store the return value, I get the CMD string, plus the output of the first function and the return value of this function[/b]

    [hr]

    function Get-APPLicenseServer {

    [CmdletBinding()]
    param
    (
    [Parameter(Mandatory=$true)] [string[]]$ServerName
    )

    $LicenseServer = ""
    for ($i = 0; $i -lt $ServerName.Length; $i++) {

    $status = Get-Service APP Server 5' -ComputerName $ServerName[$i] | select status

    Write-Host $status

    if ($status -like "*run*") {

    $LicenseServer = $ServerName[$i].ToString().ToLower()
    Write-Verbose -Message "$LicenseServer – APP Server 5 service is Running..."

    break

    } else {

    $LicenseServer = $ServerName[$i].ToString()
    Write-Verbose -Message "$LicenseServer – APP Server 5 service is Stopped..."

    }

    }

    # Load helper functions
    Write-Verbose -Message "Loaded the Get-APPLicenseStatus script"
    . "\\server\engineering_store\Development\Powershell\DEV\Functions\Get-APPLicenseStatus.ps1"

    #Create batch file to test if the APP application license is still active
    ($LicenseStatus = Get-LicenseStatus -ServerName $LicenseServer -verbose)
    $APPLicenseStatus = $LicenseStatus
    Write-Host "The APPServer License Status is: $APPLicenseStatus"

    if ($APPLicenseStatus -eq "OK" ) {

    return $LicenseServer

    } elseif ($APPLicenseStatus -ne "OK") {

    Write-Verbose -Message "$LicenseServer`: License May be Expired"

    # STOP THE SERVICE
    Stop-Service -InputObject $(Get-Service 'Nuix Server 5' -ComputerName $LicenseServer)

    #### SEND AND EMAIL ABOUT POSSIBLE ISSUE WITH LICENSE ####

    # RUN FUNCTION AGAIN
    Get-APPLicenseServer -ServerName SERVER1,SERVER2-Verbose

    break

    }

    }

    #FROM AN ISE
    Get-APPLicenseServer -ServerName SERVER1,SERVER2-Verbose

    [hr]

    What actually ends up getting returned if I try to call the 2nd function from within the ISE or from antoher function and store it as a Variable or just Write-Host the value of $LicenseServer is:

    $QueryText + return value of first function + return value of 2nd function

    all I need is the return value of the 2nd function, $LicenseServer

    What am I doing wrong???

    Thank You

  • #22966
    Profile photo of Don Jones
    Don Jones
    Keymaster

    For the benefit of someone who might read this in the future, a couple of basics first:

    Write-Host draws characters to the screen. They don't count as "output."

    The "return" keyword is equivalent to Write-Output in that it writes to the output pipeline; the difference is that return immediately exits the current scope (e.g., the function). Broadly speaking, "return" is a bit of "syntax sugar" in that it replicates behavior from other programming languages, but isn't necessarily the best way that PowerShell natively works.

    Write-Verbose writes to a different pipeline (the verbose pipeline).

    The practical upshot of this is that when a function outputs via Write-Output, its alias Write, or the Return keyword, then that output can be captured into a variable. The other important thing is that any given script only gets one pipeline. So if you're continually writing stuff to the pipeline from anyplace, and not capturing it into something like a variable, then it's going to "fall through" and wind up being the "output" of the top-level scope.

    Your approach is a very traditional programming language-style approach... but not necessarily a PowerShell approach. PowerShell functions don't return values in quite the same way that, say, a C# function does. Dot-sourcing in particular can make things harder to follow because it more or less pollutes the current scope; it basically runs whatever script you've given it IN the current scope. That's making it a little tough for me to follow just on-screen here, in fact.

    Does any of that help? I mean, I can't point to the exact error you've got, because I'd probably need to sit down and really run this line-by-line and trace what it's doing, but it seems as if the output getting mangled should relate to some of the above background.

  • #22967
    Profile photo of Kawika Moss
    Kawika Moss
    Participant

    That's helpful yes, I will see what I can do with that info. Thank You

You must be logged in to reply to this topic.