首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从.NET调用父ps1时,如何执行子ps1

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

Stack Overflow用户
提问于 2016-01-27 23:42:26
回答 1查看 238关注 0票数 1

我有一个ASP.NET应用程序,我希望调用一个Powershell脚本来获得结果。我已经做了一些挖掘,发现了很多关于PS1/2的过时信息,但没有关于PS4以上版本的信息。

我有一个PowerShell脚本,它现在可以完成一些操作,并将ArrayList输出到PowerShell控制台。Powershell脚本调用另一个PowerShell脚本:

代码语言:javascript
复制
.\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脚本的内容作为字符串传入来执行外部脚本:

代码语言:javascript
复制
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。

EN

回答 1

Stack Overflow用户

发布于 2016-01-28 00:38:23

不能保证.NET应用程序的工作目录与您从其中调用的脚本相同。

您可以使用此技巧找出调用脚本的完整路径(将第一行替换为以下代码):

代码语言:javascript
复制
$AzureSubscriptionScript = Join-Path $PSScriptRoot "Get-AzureAssistantSubscription.ps1"
& $AzureSubscriptionScript

$PSScriptRoot是一个自动变量,它将当前/调用脚本在磁盘上的位置的路径作为它的值

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35041742

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档