簡體   English   中英

從.NET調用父ps1時如何執行子ps1

[英]How do I execute child ps1's when calling the parent ps1 from .NET

我有一個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. 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。

不能保證.NET應用程序的工作目錄將與您從其中調用的腳本相同。

您可以使用此技巧來找出調用腳本的完整路徑(用第一行替換):

$AzureSubscriptionScript = Join-Path $PSScriptRoot "Get-AzureAssistantSubscription.ps1"
& $AzureSubscriptionScript

$PSScriptRoot是一個自動變量,將當前/調用腳本在磁盤上的位置路徑保存為其值

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM