Search code examples
c#powershelldynamicinvoke

C#: How to dynamically get single concatenated values on mixed types by PowerShell.Invoke()?


I have the following PowerShell script:

Get-AppxPackage | % {
    Get-AppxPackageManifest -Package $_ | % {
        $ver = $_.Package.Dependencies.TargetDeviceFamily.Name
        $min = $_.Package.Dependencies.TargetDeviceFamily.MinVersion
        $max = $_.Package.Dependencies.TargetDeviceFamily.MaxVersionTested
        $res = $ver + " (" + $min + " - "  + $max +  ")"
    }
    $_, $res
}

Its output contains the package information ($_) as well as a concatenated string ($res).

While I am able to read/map the package information by PowerShell.Invoke() in C#, I have struggles reading the concatenated string. It shows me only the length of the string but not the string itself within the dynamic variable. I also tried reading BaseObject, ImmediateBaseObject, Properties[0] and Value but no success, so far.

Here is the C# Code:

public static void Test() { 
  string script = @"Get-AppxPackage | % {
    Get-AppxPackageManifest -Package $_ | % {
      $ver = $_.Package.Dependencies.TargetDeviceFamily.Name
      $min = $_.Package.Dependencies.TargetDeviceFamily.MinVersion
      $max = $_.Package.Dependencies.TargetDeviceFamily.MaxVersionTested
      " + 
      "$res = $ver + \" (\" + $min + \" - \"  + $max +  \")\"" + @"
    }
    $_, $res
  }";    

  PowerShell powerShell = PowerShell.Create().AddScript(script);
  bool packageData = false;
  foreach (dynamic item in powerShell.Invoke().ToList()) {
    packageData ^= true;
    if (packageData) {
      // handle package data:
      // this works
    } else {
      // handle concatenated string
      // does not work - how to get its value?
    }
  }
}

Alternatively, I would like to know how to extend the PowerShell package output structure directly with the concatenated string, if possible. I tried this approach by using Add-Member or Select but it did not work as I do not really know where to put the -Name -Value and -PassThru.


Solution

  • Got it by further testing the approach to extend the package structure and thereby recognized that using single quotes within the script improves its readabilty in C#:

    public static void Test() {
      string script = @"Get-AppxPackage | % {
        Get-AppxPackageManifest -Package $_ | % {
          $ver = $_.Package.Dependencies.TargetDeviceFamily.Name
          $min = $_.Package.Dependencies.TargetDeviceFamily.MinVersion
          $max = $_.Package.Dependencies.TargetDeviceFamily.MaxVersionTested
          $res = $ver + ' (' + $min + ' - '  + $max + ')'
        }
        Add-Member -InputObject $_ -MemberType NoteProperty -Name 'Dependency' -Value $res -PassThru
      }";    
    
      PowerShell powerShell = PowerShell.Create().AddScript(script);
      foreach (dynamic item in powerShell.Invoke().ToList()) {
        string dependency = item.Dependency;
        // further package handling ...
      }
    }