GVKun编程网logo

从C#调用Powershell函数(c++调用powershell)

21

对于从C#调用Powershell函数感兴趣的读者,本文将会是一篇不错的选择,我们将详细介绍c++调用powershell,并为您提供关于C#调用PowerShell方法、Microsoft.Shar

对于从C#调用Powershell函数感兴趣的读者,本文将会是一篇不错的选择,我们将详细介绍c++调用powershell,并为您提供关于C# 调用PowerShell方法、Microsoft.SharePoint.PowerShellpipe理单元:不正确的Windows PowerShell版本3.0 当前控制台支持Window PowerShell 2.0版、Powershell – 使用Powershell对Azure AD应用程序执行“授予权限”操作、powershell 字符串 urldecoding 执行时间 [1] 可选阅读:如何从 PowerShell CLI 调用中输出机器可解析数据?的有用信息。

本文目录一览:

从C#调用Powershell函数(c++调用powershell)

从C#调用Powershell函数(c++调用powershell)

我有一个PS1文件,其中有多个Power shell功能.我需要创建一个静态DLL,它读取内存中的所有函数及其定义.然后,当用户调用DLL并传递函数名称以及函数的参数时,它调用其中一个函数.

我的问题是,是否可以这样做.即调用已读取并存储在内存中的函数?

谢谢

解决方法

这是上面提到的代码的等效C#代码
string script = "function Test-Me($param1,$param2) { \"Hello from Test-Me with $param1,$param2\" }";

using (var powershell = PowerShell.Create())
{
    powershell.AddScript(script,false);

    powershell.Invoke();

    powershell.Commands.Clear();

    powershell.AddCommand("Test-Me").AddParameter("param1",42).AddParameter("param2","foo");

    var results = powershell.Invoke();
}

C# 调用PowerShell方法

C# 调用PowerShell方法

PowerShell应为编写和运行都很方便,所以为了重复利用,经常写了一些小方法或者PS代码片段。使用的时候可能会很难找到自己想要的那个方法,如果要是有一个界面把这些代码管理起来并且调用,那就很爽了

1.创建一个powershell的方法,供C#调用,方法很简单,两个数的加法运算

function Sum

{

param([int]$first, [int]$second)

 

$result = $first + $second

 

return $result

}

 

 2. 在C#的控制台程序中创建一个私有方法,调用powershell

首先定义一个powershell存放路径的全局变量

private static string script =File.ReadAllText(@"Path\Sum.ps1");

        private static void CallPS1()

        {

            using (Runspace runspace = RunspaceFactory.CreateRunspace())

            {

                runspace.Open();

                PowerShell ps = PowerShell.Create();

                ps.Runspace = runspace;

                ps.AddScript(script);

                ps.Invoke();

 

                ps.AddCommand("Sum").AddParameters(

                    new Dictionary<string, int>()

                    {

                        {"first", 5},

                        {"second", 4}

                    }

                    );

                foreach (PSObject result in ps.Invoke())

                {

                    Console.WriteLine("CallPS1()");

                    Console.WriteLine(result);

                }

            }

        }

调用方法需要添加一个引用System.Management.Automation.dll
如果找不到可以到这个路径下找到:C:\windows\assembly\GAC_MSIL\System.Management.Automation\1.0.0.0__31bf3856ad364e35\System.Management.Automation.dll


原文链接: http://www.cnblogs.com/BoyceYang/archive/2013/06/13/3133454.html

Microsoft.SharePoint.PowerShellpipe理单元:不正确的Windows PowerShell版本3.0 当前控制台支持Window PowerShell 2.0版

Microsoft.SharePoint.PowerShellpipe理单元:不正确的Windows PowerShell版本3.0 当前控制台支持Window PowerShell 2.0版

我在我的机器上安装了SharePoint 2010,用于开发目的,而且我错误地升级到.Net 4.0和PowerShell 3.0。

解决这个问题,使用-version 2.0或-v 2 switch / arguement运行powershell并不完全正常。

所以,这个问题是如何在PowerShell中添加Microsoft.Sharepoint.PowerShellpipe理单元,在具有.Net 4.0框架的机器上?

尝试1:

Windows中的IP发现

在Windows中检测文件“copY”操作

HRESULT:0x80040154(REGDB_E_CLASSNOTREG))

对于Windows窗体,PostMessage等于自己的什么?

从C#中selectsql Server数据库中的特定logging

PS> Add-PSSnapin Microsoft.Sharepoint.Powershell The local farm is not accessible. Cmdlets with FeatureDependencyId are not registered. PS> Get-SPSite('http://myServerName/') Get-SPSite : Microsoft SharePoint is not supported with version 4.0.30319.18052 of the Microsoft .Net Runtime.

好的,所以我尝试2:

PS> powershell.exe -version 2.0 PS> Add-PSSnapin Microsoft.Sharepoint.Powershell Add-PSSnapin : Incorrect Windows PowerShell version 3.0. Windows PowerShell version 2.0 is supported in the current console. At line:1 char:13 + Add-PSSnapin <<<< Microsoft.Sharepoint.PowerShell + CategoryInfo : InvalidArgument: (Microsoft.Sharepoint.PowerShell:String) [Add-PSSnapin],PSArgumentException + FullyQualifiedErrorId : AddPSSnapInRead,Microsoft.PowerShell.Commands.AddPSSnapinCommand

我也尝试设置快捷方式的目标。 并卸载以q结尾的Windows更新

所以,这是我的错误,我无法find任何信息: 不正确的Windows PowerShell版本3.0。 当前控制台支持Windows PowerShell版本2.0。

有什么想法吗?

在哪里写日志的Windows应用程序

如何测量C#中的系统空闲时间,不包括看电影等?

如何在Windows窗体上显示必填字段

.NET EXE和DLL之间的堆栈/堆区别

采用Windows媒体基础的H.264编码

如果我打电话,它似乎为我工作

powershell.exe -version 2.0

从命令提示符而不是从Powershell调用它。

最近SharePoint 2010更新后,我可以添加PowerShell管理单元,而在版本2.0中运行PowerShell

Powershell – 使用Powershell对Azure AD应用程序执行“授予权限”操作

Powershell – 使用Powershell对Azure AD应用程序执行“授予权限”操作

我正在使用AzureAD模块创建一个Azure AD应用程序来调用Microsoft Graph API.我可以成功生成访问令牌.但是,当我尝试调用API时,我有一个错误“消息”:“无效的范围声明/角色.”.

当我在Azure门户中创建的应用程序中单击“授予权限”按钮并重试对API的调用时,调用正在运行.

我没有找到任何地方如何使用Powershell执行此“授予权限”操作.有没有办法做到这一点 ?

谢谢

达米安

解决方法

有一种简单的方法(作为管理员),它要求您为Powershell安装AzureAD和AzureRM模块,并且不受Microsoft支持.

我的博客的原始帖子/参考在这里:http://www.lieben.nu/liebensraum/2018/04/how-to-grant-oauth2-permissions-to-an-azure-ad-application-using-powershell-unattended-silently/

应该帮助您完成此任务的特定代码示例:

Function Grant-OAuth2PermissionsToApp{
Param(
    [Parameter(Mandatory=$true)]$Username,#global administrator username
    [Parameter(Mandatory=$true)]$Password,#global administrator password
    [Parameter(Mandatory=$true)]$azureAppId #application ID of the azure application you wish to admin-consent to
)

$secpasswd = ConvertTo-securestring $Password -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ($Username,$secpasswd)
$res = login-azurermaccount -Credential $mycreds
$context = Get-AzureRmContext
$tenantId = $context.Tenant.Id
$refreshToken = @($context.TokenCache.ReadItems() | where {$_.tenantId -eq $tenantId -and $_.ExpiresOn -gt (Get-Date)})[0].RefreshToken
$body = "grant_type=refresh_token&refresh_token=$($refreshToken)&resource=74658136-14ec-4630-ad9b-26e160ff0fc6"
$apiToken = Invoke-RestMethod "https://login.windows.net/$tenantId/oauth2/token" -Method POST -Body $body -ContentType 'application/x-www-form-urlencoded'
$header = @{
'Authorization' = 'Bearer ' + $apiToken.access_token
'X-Requested-With'= 'XMLHttpRequest'
'x-ms-client-request-id'= [guid]::NewGuid()
'x-ms-correlation-id' = [guid]::NewGuid()}
$url = "https://main.iam.ad.ext.azure.com/api/RegisteredApplications/$azureAppId/Consent?onBehalfOfAll=true"
Invoke-RestMethod -Uri $url -Headers $header -Method POST -ErrorAction Stop
}

powershell 字符串 urldecoding 执行时间 [1] 可选阅读:如何从 PowerShell CLI 调用中输出机器可解析数据?

powershell 字符串 urldecoding 执行时间 [1] 可选阅读:如何从 PowerShell CLI 调用中输出机器可解析数据?

注意,如果您将输入数据作为字符串文字传递,如问题中的示例调用(而不是作为命令的输出):

  • 如果您从 交互式 cmd.exe 会话中调用,%C4%9B%C5%A1%C4%8D%C5%99%C5%BE%C3%BD%C3%A1%C3%AD%C3%A9%C5%AF%C3%BA 按原样工作 - 除非配对 % 之间的任何令牌实例恰好是现有环境变量的名称(这似乎不太可能)。

  • 批处理文件中,您必须转义 % 字符。通过加倍 - 见this answer;您可以通过对原始字符串应用以下 PowerShell 操作来获得:

    '%C4%9B%C5%A1%C4%8D%C5%99%C5%BE%C3%BD%C3%A1%C3%AD%C3%A9%C5%AF%C3%BA' -replace '%','%%'
    

是不是因为使用了.NET对象?

  • 是的,powershell.exe,作为基于 .NET 的应用程序需要启动后者的运行时 (CLR),这在性能方面非常重要。

  • 此外,powershell.exe 默认加载其 $PROFILE 变量中列出的初始化文件,这可能需要额外的时间。

    • 传递 -NoProfile CLI 选项来禁止它。

也有一些 C 语言编写的、闪电般快速的 urldecode.exe 实用程序,但不幸的是它不吃 STDIN。

如果是这样,如果可行,将数据作为参数传递;例如:

urldecode.exe "%C4%9B%C5%A1%C4%8D%C5%99%C5%BE%C3%BD%C3%A1%C3%AD%C3%A9%C5%AF%C3%BA"

如果数据来自另一个命令的输出,可以使用for /f 先捕获到一个变量中,然后传递后者。


毕竟,如果您确实需要调用 powershell.exe,PowerShell 的 CLI:

在优化性能方面你无能为力:

  • 按照建议添加 -NoProfile
  • 将输入数据作为参数传递
  • 避免不必要的调用,例如 Write-Host,而是依赖 PowerShell 的隐式输出行为[1]
powershell.exe -NoProfile -c "Add-Type -AssemblyName System.Web;[System.Web.HttpUtility]::UrlDecode('%C4%9B%C5%A1%C4%8D%C5%99%C5%BE%C3%BD%C3%A1%C3%AD%C3%A9%C5%AF%C3%BA')"

[1] 可选阅读:如何从 PowerShell CLI 调用中输出机器可解析数据

注意:假设示例命令是从 cmd.exe/PowerShell 外部运行的。

  • PowerShell 的 CLI 仅支持 text 作为输出,不支持原始字节数据。

  • 为了输出数据供以后程序处理,您可能必须明确确保输出的内容机器可解析 而不是用于仅显示的东西。

两种基本选择

  • 依靠 PowerShell 的默认输出格式来输出字符串(文本)开头的内容,以及数字 - 但对于小数和非常大或小的非整数数字,可能需要额外的努力。

  • 明确使用结构化、基于文本的数据格式,例如 CSV 或 Json,来表示复杂对象


依赖 PowerShell 的默认输出格式:

  • 如果输出数据是本身文本(字符串),则不需要额外的工作。这适用于您的情况,因此只需隐式输出从 [System.Web.HttpUtility]::UrlDecode() 调用返回的字符串就足够了:

    # A simple example that outputs a 512-character string; note that 
    # printing to the _console_ (terminal) will insert line breaks for 
    # *display*,but the string data itself does _not_ contain any 
    # (other than a single _trailing one),irrespective of the 
    # console window width:
    powershell -noprofile -c "'x' * 512"
    
  • 如果输出数据包含数字,并且您的代码必须在有效的不同文化下运行,则您可能必须应用显式的、文化不变的格式

    • 真正的整数类型不需要特殊处理,因为它们的字符串表示实际上是文化中性的。

    • 但是,小数数字([double][decimal])确实使用了当前文化的小数点,后面的处理可能不会期待:

      # With,say,culture fr-FR (French) in effect,this outputs
      # "1,2",i.e. uses a *comma* as the decimal mark.
      powershell -noprofile -c "1.2"
      
      # Simple workaround: Let PowerShell *stringify* the number explicitly
      # in an *expandable* (interpolating) string,which uses
      # the *invariant culture* for formatting,where the decimal
      # mark is *always "." (dot).
      # The following outputs "1.2",irrespective of what culture is in effect.    
      powershell -noprofile -c " $num=1.2; \"$num\" "
      
    • 最后,非常大和非常小的 [double] 值会导致输出指数符号(例如,5.1E-07 代表 0.00000051);为了避免这种情况,需要 explicit number formatting,这可以通过 .ToString() 方法完成:

      # The following outputs 0.000051" in all cultures,as intended.
      powershell -noprofile -c "$n=0.000051; $n.ToString('F6',[cultureinfo]::InvariantCulture)"
      
  • 如果您想以机器可解析的形式输出复杂对象的表示,则需要做更多的工作,如下一节所述强>.

    • 在这种情况下,依赖 PowerShell 的默认输出格式不是一个选项,因为隐式输出和(等效的显式 Write-Output 调用)会导致 CLI 应用 -display-only 格式,对人类观察者有意义,但不能可靠地解析

      # Produces output helpful to the *human observer*,but isn't
      # designed for *parsing*.
      # `Get-ChildItem` outputs [System.IO.FileSystemInfo] objects.
      powershell -noprofile -c "Get-ChildItem /"
      
    • 请注意,Write-Host 的使用不是替代Write-Host 根本上不是为数据设计的 输出,以及它为复杂对象创建的文本表示对于人类观察者来说通常甚至没有意义 - 请参阅 this answer 了解更多信息。


使用结构化、基于文本的数据格式,例如 CSV 或 Json:

注意:

  • 假设,最简单的方法是使用 CLI 的 -OutputFormat Xml 选项,该选项使用 PowerShell 本身用于远程处理和后台作业的基于 XML 的 CLIXML 格式序列化输出 - 请参阅 this answer。

  • 但是,这种格式只有 PowerShell 本身才能理解,第三方应用程序要解析它,它们必须基于 .NET 并使用 PowerShell SDK。

    • 此外,如果您从 PowerShell 调用另一个 PowerShell 实例,并且将命令指定为作为脚本块自动,则此格式将自动用于序列化和反序列化 /em> ({ ... }) - 参见 this answer。但是,很少需要从 PowerShell 本身调用 PowerShell CLI,直接调用 PowerShell 代码和脚本可提供完整的类型保真度以及更好的性能。
  • 最后,请注意所有序列化格式,包括下面讨论的 CSV 和 JSON,在忠实地表示数据的所有方面方面都有局限性,尽管 -OutputFormat Xml 最接近。

PowerShell 带有 ConvertTo-CsvConvertTo-Json 等 cmdlet,可以轻松地将输出转换为结构化 CSV 和 JSON 格式。

以使用Get-Item调用获取PowerShell安装目录($PSHOME)信息为例;在这种情况下,Get-Item 输出一个 System.IO.DirectoryInfo 实例:

  • ConvertTo-Csv 的使用:
C:\>powershell -noprofile -c "Get-Item $PSHOME | ConvertTo-Csv -NoTypeInformation"
"PSPath","PSParentPath","PSChildName","PSDrive","PSProvider","PSIsContainer","Mode","BaseName","Target","LinkType","Name","FullName","Parent","Exists","Root","Extension","CreationTime","CreationTimeUtc","LastAccessTime","LastAccessTimeUtc","LastWriteTime","LastWriteTimeUtc","Attributes"
"Microsoft.PowerShell.Core\FileSystem::C:\Windows\System32\WindowsPowerShell\v1.0","Microsoft.PowerShell.Core\FileSystem::C:\Windows\System32\WindowsPowerShell","v1.0","C","Microsoft.PowerShell.Core\FileSystem","True","d-----","System.Collections.Generic.List`1[System.String]","C:\Windows\System32\WindowsPowerShell\v1.0","WindowsPowerShell","C:\",".0","12/7/2019 4:14:52 AM","12/7/2019 9:14:52 AM","3/14/2021 10:33:10 AM","3/14/2021 2:33:10 PM","11/6/2020 3:52:41 AM","11/6/2020 8:52:41 AM","Directory"

注意:PowerShell (Core) 7+ 中不再需要 -NoTypeInformation

  • 使用 ConvertTo-Json
C:\>powershell -noprofile -c "Get-Item $PSHOME | ConvertTo-Json -Depth 1"
{
    "Name":  "v1.0","FullName":  "C:\\Windows\\System32\\WindowsPowerShell\\v1.0","Parent":  {
                   "Name":  "WindowsPowerShell","FullName":  "C:\\Windows\\System32\\WindowsPowerShell","Parent":  "System32","Exists":  true,"Root":  "C:\\","Extension":  "","CreationTime":  "\/Date(1575710092565)\/","CreationTimeUtc":  "\/Date(1575710092565)\/","LastAccessTime":  "\/Date(1615733476841)\/","LastAccessTimeUtc":  "\/Date(1615733476841)\/","LastWriteTime":  "\/Date(1575710092565)\/","LastWriteTimeUtc":  "\/Date(1575710092565)\/","Attributes":  16
               },"Exists":  true
    // ...
}

由于 JSON 是一种分层数据格式,序列化深度必须用 -Depth 进行限制,以防止在序列化任意 .NET 类型时“失控”序列化;对于仅由原始 .NET 类型组成的 [pscustomobject][hashtable] 对象图,这不是必需的。

我们今天的关于从C#调用Powershell函数c++调用powershell的分享就到这里,谢谢您的阅读,如果想了解更多关于C# 调用PowerShell方法、Microsoft.SharePoint.PowerShellpipe理单元:不正确的Windows PowerShell版本3.0 当前控制台支持Window PowerShell 2.0版、Powershell – 使用Powershell对Azure AD应用程序执行“授予权限”操作、powershell 字符串 urldecoding 执行时间 [1] 可选阅读:如何从 PowerShell CLI 调用中输出机器可解析数据?的相关信息,可以在本站进行搜索。

本文标签: