简体   繁体   English

从.NET调用父ps1时如何执行子ps1

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

I have an ASP.NET application that I am wishing to call a Powershell Script to get results. 我有一个ASP.NET应用程序,希望调用Powershell脚本来获得结果。 I've done some digging and come up with a lot of very dated information relating to PS1/2 but nothing for PS4 upwards. 我做了一些挖掘工作,并提出了许多与PS1 / 2有关的非常过时的信息,但对于PS4或更高版本则没有任何信息。

I have a PowerShell script that presently completes some operations and outputs an ArrayList to the PowerShell console. 我有一个PowerShell脚本,该脚本当前完成一些操作并将ArrayList输出到PowerShell控制台。 The Powershell Script calls another PowerShell script: 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

I also have the following .NET code that attempts to execute the outer script by having the content of the PS1 script passed in as a string: 我还具有以下.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;
        }
    }
}

The issue is that if I call the ps1 from .NET, it fails complaining that 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. 问题是,如果我从.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. If I execute the ps1 from PowerShell, it executes without issue. 如果我从PowerShell执行ps1,则它执行没有问题。

If I copy and paste the content of the Get-AzureSubscription.ps1 into the ps1 that is directly called by .NET instead of linking the two scripts, everything is passed back to .NET successfully. 如果我将Get-AzureSubscription.ps1的内容复制并粘贴到.NET直接调用的ps1中,而不是链接两个脚本,则所有内容都会成功传递回.NET。

There's no guarantee that the working directory of the .NET application will be the same as the script you invoke from within it. 不能保证.NET应用程序的工作目录将与您从其中调用的脚本相同。

You can use this trick to figure out the full path to the invoking script (replace the first line with this): 您可以使用此技巧来找出调用脚本的完整路径(用第一行替换):

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

$PSScriptRoot is an automatic variable that holds the path of the current/invoking script's location on disk as its value $PSScriptRoot是一个自动变量,将当前/调用脚本在磁盘上的位置路径保存为其值

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 通过ASP.NET下载powershell(.ps1)文件 - Download powershell (.ps1) file via ASP.NET 在服务器上执行powershell .ps1文件并查看结果C#asp.net - Executing powershell .ps1 file on server and viewing results C# asp.net 无法加载 .ps1,因为在此系统上禁用了脚本的执行 - .ps1 cannot be loaded because the execution of scripts is disabled on this system 如何确定何时在父级的子级中单击按钮-ASP.NET - How do you determine when a button is clicked in the child on the parent - ASP.NET 如何在ASP.NET MVC的父域模型中将此子模型引用传递给虚拟ICollection? - How do I pass this child model reference to a virtual ICollection in parent domain model in ASP.NET MVC? 如何将子节点分组到相应的父节点? - How do I group my child nodes to it's corresponding parent node? 如何从父项的style属性中设置子项元素的CSS样式? - How do you set the CSS styles of child elements from within the parent's style attribute? ASP.NET 3.5:禁用父控件时如何防止子控件被禁用? - ASP.NET 3.5: How to keep child controls from beind disabled when parent control is disabled? 在父级中禁用时,如何为子自定义控件启用ViewState? - How do I enable ViewState for child custom controls when disabled in parent? 如何将数据从子页面传递到调用@Body的页面? - How do I pass data up from the child page to the page calling @Body?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM