Search code examples
c#powershell.net-coredhcp

My PowerShell Script does not work from dotnet application


I run PowerShell scripts from within my .NET Core 3 web application to perform DHCP server tasks.

This one finds out what ScopeID I should use for a new DHCP reservation. It works perfectly when I run it in PowerShell ISE on the web server. When it runs from the the web application on the same server it always returns null.

$DhcpServer = 'MY_DHCP_SERVER'
$IPaddress = '10.140.98.143'
$ScopeId = $null

'PowerShell version: ' + [string]$PSVersionTable.PSVersion

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Unrestricted -Force

$all_scopes = Get-DhcpServerv4Scope -ComputerName $DhcpServer
if($all_scopes) {
    $number_of_scopes = $all_scopes.Count
    $counter = -1
    $hit_in_scope = $null

    Do {
        $counter = $counter+1
                                         
        If (([version]($all_scopes[$counter]).StartRange.IPAddressToString) -le ([version]$IPaddress) -and ([version]$IPaddress) -le ([version]($all_scopes[$counter]).EndRange.IPAddressToString))
        {
            $hit_in_scope = ($all_scopes[$counter]).ScopeID
        }

    } until ($counter -eq $number_of_scopes -or $hit_in_scope -ne $null)
    
    $ScopeId = $hit_in_scope.IPAddressToString
}

$ScopeId

Output in PowerShell ISE:

PowerShell version: 5.1.17763.2931
10.140.98.128

The log when the same script is run in web application:

2022-11-01 13:43:00.643 +01:00 [DBG] results: System.Management.Automation.PSDataCollection`1[System.Management.Automation.PSObject]
2022-11-01 13:43:00.644 +01:00 [DBG] results.Count: 2
2022-11-01 13:43:00.644 +01:00 [DBG] resultString: PowerShell version: 7.0.5
2022-11-01 13:43:00.644 +01:00 [DBG] resultString: 
2022-11-01 13:43:00.674 +01:00 [ERR] PowerShell response is null or empty

Here is how I run the script in my application:

    private async Task<string> RunPowershellScriptWithReturnStringValue(string script, string errorMessage)
    {
        string resultString = null;

        using (var psInstance = PowerShell.Create())
        {
            var results = await psInstance.AddScript(script).InvokeAsync();
            //psdatacollection<psobject>
            Log.Debug($"results: {results.ToString()}");
            Log.Debug($"results.Count: {results.Count}");
            if (results != null)
            {
                foreach (var psObject in results)
                {
                    resultString = psObject != null ? psObject.ToString() : null;
                    Log.Debug($"resultString: {resultString}");
                }
            }
            if (psInstance.HadErrors)
            {
                Log.Error(errorMessage);
                psInstance.LogErrors();
            }
        }
        if (string.IsNullOrEmpty(resultString))
        {
            Log.Error("PowerShell response is null or empty");
            Log.Debug("PowerShell script follows");
            Log.Debug(script);
        }
        return resultString;
    }

I find it strange that I get two different versions of PowerShell. Both scripts are run on the same server.

Is there a way of specifying what PowerShell version I want to use when I call psInstance.AddScript(script).InvokeAsync()? How?

Or should I change the script so that it works with PowerShell 7.0.5? How?

Target Framework is .NET Core 3.1


Solution

  • ".IPAddressToString" does not exist in PowerShell 7. If I just remove all of those, my script works as expected from my .Net Core app on the web server.

    (Then it does not work when I run it on my local computer since I don't have PowerShell 7. On the other hand I don't have the DHCP server module locally either. When I run this locally I use Invoke-Command to run the PowerShell commands on the server so I already have a totally different PowerShell script. I guess this will be my solution.)