问题标签 [powershell-hosting]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
powershell - 从 C# 异常调用的 PowerShell AddCommand
我正在尝试构建一个 C# 控制台应用程序,该应用程序执行一系列针对 Azure 订阅运行的 PowerShell 命令。
我以为它会呈现一个交互式登录框,然后继续运行。相反,这是抛出:
System.Management.Automation.dll 中出现“System.Management.Automation.CommandNotFoundException”类型的未处理异常附加信息:术语“$cred = Get-Credential”未被识别为 cmdlet、函数、脚本文件的名称, 或可操作...
如果我从 CMD 启动 PowerShell,然后键入
$cred = 获取凭据
我看到了默认的交互式登录框,用户可以输入凭据,它们被捕获到 $cred 并且我可以继续。
什么是在 C# 中使其工作的正确命令集?
谢谢。
powershell - 通过 PSSessionConfiguration 文件获取 Enter-PSHostProcess 行为
场景:其中嵌入了 Powershell 主机的 Windows 服务。单个运行空间在启动时分配。多dll解决方案。
要求:需要访问正在运行的服务中的 .NET 类。从本地 Powershell 实例使用
...因为我可以访问 .NET 类,所以正是我想要的。
问题:如何使用 Enter-PSSession 将这种 Powershell 行为提供给远程端点到自定义端点?从 Register-PSSessionConfiguration 我们可以指定一个 dll,但这会产生一个进程并且不会连接到正在运行的实例。对通过 HTTPS 或命名管道编写代理不感兴趣,但使用 Powershell 中提供的本机功能来支持 .NET。
是否可以通过 PSSessions 扩展它?还是我们只需要先执行 Enter-PSSession 或 Invoke-Command?
powershell - 如何确定 Write-Host 是否适用于当前主机
在可以针对任何合理的主机实现运行的脚本中,是否有任何理智、可靠的合同规定是否Write-Host
在给定的 PowerShell 主机实现中受支持?
(假设我理解Write-Host
and Write-Output
/之间的区别,并且Write-Verbose
我肯定想要Write-Host
语义,如果支持的话,对于这个特定的人类可读文本。)
我想过尝试询问$Host
变量,或者$Host.UI
/$Host.UI.RawUI
但我发现的唯一相关差异是:
在
$Host.Name
:- Windows powershell.exe 命令行有
$Host.Name = 'ConsoleHost'
- 伊势有
$Host.Name = 'Windows PowerShell ISE Host'
- SQL Server 代理作业步骤有
$Host.Name = 'Default Host'
- 我没有安装任何非 Windows 版本,但我希望它们有所不同
- Windows powershell.exe 命令行有
在
$Host.UI.RawUI
:- Windows powershell.exe 命令行返回所有属性的值
$Host.UI.RawUI
- ISE
$null
对 的某些属性不返回任何值(或 )$Host.UI.RawUI
,例如$Host.UI.RawUI.CursorSize
- SQL Server 代理作业步骤不返回任何值
$Host.UI.RawUI
- 同样,我无法签入任何其他平台
- Windows powershell.exe 命令行返回所有属性的值
维护$Host.Name
支持的值列表Write-Host
似乎有点负担,尤其是现在 PowerShell 是跨平台的。我会合理地希望脚本能够从任何主机调用并且只是做正确的事情。
背景
我编写了一个脚本,可以从 PowerShell 命令提示符、ISE 或 SQL Server 代理作业中合理运行。该脚本的输出完全是文本的,供人类阅读。从命令提示符或 ISE 运行时,输出使用Write-Host
.
SQL Server 作业可以通过两种不同的方式设置,并且都支持将输出捕获到 SQL Server 代理日志查看器中:
通过 CmdExec 步骤,这是简单的命令行执行,其中 Job Step 命令文本是可执行文件及其参数,因此您调用 powershell.exe 可执行文件。捕获的输出是过程的标准输出/标准输出:
/li>通过 PowerShell 步骤,其中 Job Step 命令文本是由其自己的嵌入式 PowerShell 主机实现解释的原始 PS 脚本。捕获的输出是通过
/li>Write-Output
or写入的任何内容Write-Error
:
由于 SQL Server 主机实现的其他一些弱点,我发现您可以使用Write-Output
或发出输出Write-Error
,但不能同时使用。如果作业步骤失败(即如果您throw
或Write-Error 'foo' -EA 'Stop'
),您只会在日志中获得错误流,如果成功,您只会在日志中获得输出流。
此外,嵌入式 PS 实现不支持Write-Host
. 至少到 SQL Server 2016,Write-Host
抛出一个System.Management.Automation.Host.HostException
带有消息A command that prompt the user failed because the host program or the command type does not support user interaction。
为了支持我所有的用例,到目前为止,我开始使用一个自定义函数Write-Message
,该函数基本上设置为(简化):
从 SQL Server 2019(可能更早)开始,它似乎Write-Host
不再在嵌入式 SQL Server 代理 PS 主机中引发异常,而是一个不向输出或错误流发出任何内容的空操作。由于没有例外,我的脚本Write-Message
函数无法再可靠地检测它是否应该使用Write-Host
或StringBuilder.AppendLine
。
SQL Server 代理作业的基本解决方法是使用更成熟的 CmdExec 步骤类型(其中Write-Output
和Write-Host
两者都被捕获为标准输出),但我更喜欢 PowerShell 步骤类型,因为(除其他原因外)它能够可靠地拆分命令多行,所以我很想看看是否有更全面的、基于 PowerShell 的方法来解决是否Write-Host
对我所在的主机有用的问题。
c# - 在 C# 中,使用脚本将命令添加到 PowerShell InitialSessionState 并使其可从 C# 中发现
有没有办法找到使用 ImportPSModule() 导入到 InitialSessionState 中的函数?
我有这个围绕 PowerShell 的包装器来运行由我的应用程序自托管的脚本(为简洁起见,删除了注释和错误检查)
当我使用 engine.AddCommand() 添加类型时,它们会按预期显示在 engine.ListCommands() 中。我现在想让用户拥有一组他们预先定义的自定义函数,我将通过 ImportPSModule() 导入这些函数。最后,我希望能够将 UI 中的这些命令列为可用命令。
我创建了一个非常简单的模块(init.psm1)
并测试导入它,但功能不显示为可用命令。(尽管用户脚本可以很好地使用它们。)
我根据这个问题查看了 System.Management.Automation.Language.Parser.ParseFile并且可以在 {function} 之后检查令牌,但这似乎是一种迂回的方法。(目前,这是我最好的选择。)
我考虑过使用 运行一个小脚本Get-ChildItem function:
,但使用时 Get-ChildItem 不可用InitialSessionState.CreateDefault()
(我不想使用 InitialSessionState.Create()
。我的场景需要引擎比这更锁定。)
我可以使用其他选项来获取用户定义的函数列表吗?只要用户可以将它们作为 powershell 代码提供,以另一种方式导入它们是可以接受的。
谢谢!
编辑 重新阅读文档,似乎我错过了这一非常重要的行:
所以我将把这个问题稍微更新为“有没有办法从可以添加到 initialSessionState.Commands 的脚本文件中创建 SessionStateCommandEntry()?”
c# - 使用 C# 中的 PowerShell 主机如何获取输出?
具有以下 NET 5 控制台应用程序:
调用似乎没有错误地执行,但是输出去哪里了?我已经尝试了AddCommand
and AddStatement
,并且还检查了ps
调试器中的变量,没有输出迹象。我确实发现了,ps.Streams.Information
但它是空的。
c# - C# 在调用 Invoke() 后将命令添加到长时间运行的托管 PowerShell 会话
我正在尝试(最终)为长时间运行的 .exe 应用程序(例如加密节点或游戏服务器)编写 C# 服务包装器。到目前为止,我已经编写了一个输出 .exe 输出的小型 PowerShell 主机(当前输出到控制台,最终它将转到其他地方)和一个每秒输出时间的小型示例应用程序,并Console.ReadLine()
正在寻找“停止”以停止执行。目前我能够托管示例应用程序并将输出正确定向(到控制台),但我需要知道如何在PowerShell.Invoke()
调用后添加命令。
游戏服务器之类的程序通常具有可用的命令,例如“保存”或“退出”来控制服务器。程序在托管的 PowerShell 会话中运行后,我想添加一个“停止”命令来停止示例应用程序,但我不知道如何。
我的目标.NET 5.0
和使用Microsoft.PowerShell.SDK
包
下面是我的代码
托管程序
注意这里第 15 行, Console.WriteLine("Started");
, 将执行,但以下语句(包括和 after Console.WriteLine("Attempting stop");
)不会执行,或者至少不会进入控制台。
示例应用程序
这个小应用程序的目标是模拟一个长时间运行的程序(如游戏服务器)并且需要一些输入(如“停止”)才能正确退出程序。这主要是为了完整性
Invoke()
由于示例程序需要读取“停止”才能正确停止,因此在托管 PowerShell 对象上已经调用之后,如何以编程方式发送它?本质上是为了复制坐在控制台前的用户,但不是用户,而是一个程序。