Similar to the answer to your previous question, the following self-contained sample code demonstrates that the approach works in principle, after correcting the following problems in your code:
An .AddStatement() call is missing between the .AddScript() and the .AddCommand() call; this is necessary for the (script block-based) Import-Module call and the Get-RowAndPartitionKeys call to be treated as separate statements.
Pseudo-code line string scriptContents = "Import-Module 'C:\Users\...\Powershell.dll"; is missing a closing ' (possibly just an artifact of posting here).
Also, troubleshooting code is added below.
While the orchestration code is in PowerShell, actual C# projects, compiled via the .NET SDK are used, in combination with version 7.1.2 of the PowerShell (Core) SDK package, Microsoft.PowerShell.SDK.
After running the code, which creates and runs the test projects, you can inspect and experiment with them yourself (./module is the project for the module DLL that defines the Get-RowAndPartitionKeys cmdlet, ./app is the project for the application that calls it):
$tmpDir = (New-Item -Force -Type Directory (Join-Path temp: $PID)).FullName
$tmpModuleDir = (New-Item -Force -Type Directory (Join-Path $tmpDir module)).FullName
$tmpAppDir = (New-Item -Force -Type Directory (Join-Path $tmpDir app)).FullName
$tmpPublishDir = (New-Item -Force -Type Directory (Join-Path $tmpDir publish)).FullName
$tmpModuleDll = Join-Path $tmpPublishDir module.dll
Push-Location
# ---
Write-Verbose -vb "Creating module DLL with sample cmdlet..."
Set-Location $tmpModuleDir
dotnet new classlib --force >$null || $(exit $LASTEXITCODE)
dotnet add package Microsoft.PowerShell.SDK >$null || $(exit $LASTEXITCODE)
@'
using System;
using System.Collections.Generic;
using System.Management.Automation;
namespace demo {
public class GetRowAndPartitionKeys : Cmdlet
{
public List<string> Properties { get; set; }
}
[Cmdlet( VerbsCommon.Get, "RowAndPartitionKeys" )]
public class GetRowAndPartitionKeyCmd : GetRowAndPartitionKeys
{
protected override void ProcessRecord()
{
WriteObject ("Hi");
}
}
}
'@ | Set-Content Class1.cs
dotnet publish -o $tmpPublishDir >$null || $(exit $LASTEXITCODE)
# ---
Write-Verbose -vb "Creating console application that imports the module DLL and calls the sample cmdlet..."
Set-Location $tmpAppDir
dotnet new console --force >$null || $(exit $LASTEXITCODE)
dotnet add package Microsoft.PowerShell.SDK >$null || $(exit $LASTEXITCODE)
@"
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Threading.Tasks;
namespace demo {
public static class App {
static void Main(string[] args)
{
var unused = new Foo().RunScript().Result;
}
}
public class Foo {
public async Task<IEnumerable<object>> RunScript()
{
string scriptContents = @"Import-Module -Verbose ""$tmpModuleDll""";
using(PowerShell ps = PowerShell.Create())
{
ps.AddScript(scriptContents).AddStatement().AddCommand("Get-RowAndPartitionKeys");
var pipelineObjects = await ps.InvokeAsync().ConfigureAwait( false );
// --- TROUBLESHOOTING CODE
// Print verbose output from the Import-Module call
foreach (var v in ps.Streams.Verbose) { Console.WriteLine("VERBOSE: " + v.ToString()); }
// Print any errors.
foreach (var e in ps.Streams.Error) { Console.WriteLine("ERROR: " + e.ToString()); }
// ---
foreach (var item in pipelineObjects)
{
Console.WriteLine(item.BaseObject.ToString());
}
return pipelineObjects;
}
}
}
}
"@ | Set-Content Program.cs
# ---
Write-Verbose -vb "Compiling and invoking the console application..."
dotnet run
Pop-Location
Write-Verbose -vb @"
The test projects are located in $tmpDir.
To clean up, run:
Remove-Item "$tmpdir" -Recurse
"@
On my Windows 10 machine (running from PowerShell 7.1.2), I get:

As you can see:
- the verbose output confirms that the cmdlet was properly imported
- the
Hi shows that the cmdlet was successfully called.