我有一个ASP.NET应用程序,我希望调用Powershell脚本来获得结果。我已经做了一些挖掘,并提出了许多与PS1 / 2相关的非常过时的信息,但PS4向上没有任何信息。
我有一个PowerShell脚本,目前完成一些操作并将一个ArrayList输出到PowerShell控制台。 Powershell脚本调用另一个PowerShell脚本:
.\Get-AzureSubscription.ps1
$environments = New-Object System.Collections.ArrayList
$resourceGroups = Get-AzureRMResourceGroup
foreach($thisResourceGroup in $resourceGroups)
{
$resourceGroupVMs = Get-AzureRmVM -ResourceGroupName $thisResourceGroup.ResourceGroupName
$environment = New-Object -TypeName PSObject
$environment | Add-Member -MemberType NoteProperty -Name ResourceGroupName -Value $thisResourceGroup.ResourceGroupName
$environment | Add-Member -MemberType NoteProperty -Name Id -Value $thisResourceGroup.ResourceId
$machines = New-Object System.Collections.ArrayList
foreach($thisMachine in $resourceGroupVMs)
{
$machine = New-Object -TypeName PSObject
$machine | Add-Member -MemberType NoteProperty -name Name -value $thisMachine.Name
$machine | Add-Member -MemberType NoteProperty -name ResourceGroupName -value $thisResourceGroup.ResourceGroupName
$status = Get-AzureRmVM -ResourceGroupName $thisResourceGroup.ResourceGroupName -Name $thisMachine.Name -Status | `
Select-Object -ExpandProperty Statuses | `
Where-Object { $_.Code.StartsWith("PowerState") } | `
Select-Object -ExpandProperty Code
$regex = [Regex] '\/(.*?)$'
$machine | Add-Member -MemberType NoteProperty -name Status -value $regex.Match($status).Groups[1].Value
$machines.Add($machine) > $null;
}
$environmentStatuses = $machines | Select-Object ResourceGroupName -ExpandProperty Status | Group-Object ResourceGroupName, Status
$environment | Add-Member -MemberType NoteProperty -name Statuses -value $environmentStatuses
$environments.Add($environment) > $null;
}
$environments
我还有以下.NET代码,它试图通过将PS1脚本的内容作为字符串传入来执行外部脚本:
public Collection<PSObject> RunScript(string script, Dictionary<string, string> parameters = null)
{
// Validate parameters
if (string.IsNullOrEmpty(script)) { throw new ArgumentNullException(nameof(script)); }
RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
using (Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration))
{
runspace.Open();
using (RunspaceInvoke invoker = new RunspaceInvoke(runspace))
{
invoker.Invoke("Set-ExecutionPolicy Unrestricted");
Pipeline pipeline = runspace.CreatePipeline();
Command scriptCommand = new Command(script, true);
parameters?.Select(kvp => new CommandParameter(kvp.Key, kvp.Value))
.ForEach(scriptCommand.Parameters.Add);
pipeline.Commands.Add(scriptCommand);
var result = pipeline.Invoke();
return result;
}
}
}
问题是,如果我从.NET调用ps1,它就会失败抱怨The term '.\Get-AzureSubscription.ps1' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
如果我从PowerShell执行ps1,它会毫无问题地执行。
如果我将Get-AzureSubscription.ps1
的内容复制并粘贴到由.NET直接调用的ps1中而不是链接这两个脚本,则所有内容都会成功传递回.NET。
答案 0 :(得分:1)
无法保证.NET应用程序的工作目录与您从其中调用的脚本相同。
您可以使用此技巧找出调用脚本的完整路径(用此替换第一行):
$AzureSubscriptionScript = Join-Path $PSScriptRoot "Get-AzureAssistantSubscription.ps1"
& $AzureSubscriptionScript
$PSScriptRoot
是一个自动变量,它将当前/调用脚本在磁盘上的位置路径保存为其值