[英]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.