Powershell 区别于;新对象WindowsPrincipal([WindowsIdentity]::GetCurrent())”引用;及;[WindowsPrincipal][WindowsIdentity]::GetCurrent();

Powershell 区别于;新对象WindowsPrincipal([WindowsIdentity]::GetCurrent())”引用;及;[WindowsPrincipal][WindowsIdentity]::GetCurrent();,powershell,Powershell,我正在尝试检查Powerhell脚本是否以管理员身份运行。 搜索完web后,我得到了一些运行良好的示例代码。 为了获得WindowsPrincipal对象,我找到了如下两个示例代码 ## First PowerShell script New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent()) // C# var wp = new WindowsPrinci

我正在尝试检查Powerhell脚本是否以管理员身份运行。 搜索完web后,我得到了一些运行良好的示例代码。
为了获得
WindowsPrincipal
对象,我找到了如下两个示例代码

## First PowerShell script
New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())

// C#
var wp = new WindowsPrincipal(WindowsIdentity.GetCurrent());
第一:

New Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
第二:

[Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()
第二个让我困惑

根据,我知道
[]
是一个cast操作符。 据介绍,PowerShell是在.NET框架上构建的。在我看来,这意味着上述两个PowerShell脚本可以转换为C。
所以我试试看。
当我将第一个PowerShell脚本转换为C#时。它的工作原理如下

## First PowerShell script
New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())

// C#
var wp = new WindowsPrincipal(WindowsIdentity.GetCurrent());
但是当我尝试将第二个PowerShell脚本转换为C#时。我得到编译错误。IDE告诉我不能将
WindowsIdentity
强制转换为
WindowsPrincipal

## Second PowerShell script
[Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()

// both C# code below cause compile error
var wp = System.Security.Principal.WindowsIdentity.GetCurrent() as System.Security.Principal.WindowsPrincipal;
var wp2 = (System.Security.Principal.WindowsPrincipal)System.Security.Principal.WindowsIdentity.GetCurrent();
正如我在C#上尝试的那样,
System.Security.Principal.WindowsIdentity
类型不能直接转换为
System.Security.Principal.WindowsPrincipal
类型。但是为什么第二个PowerShell脚本可用?
或者第二个PowerShell脚本中的
[]
运算符不是类型转换运算符吗?
也许此运算符的作用不仅仅是转换对象类型?
第一个PowerShell脚本和第二个PowerShell脚本有什么区别?

我还遗漏了什么吗?

TLDR:PowerShell可以做魔法。C#不会变魔术

PowerShell可以同时玩电锯、保龄球销和球

C#只有在提前定义球的情况下才能玩杂耍。试图在杂耍例程中添加新链锯会导致杂耍者(编译器)抱怨


问题是函数、对象类型之间的差异,以及如何强制转换对象类型

System.Security.Principal
是基本的.NET库。该库可供C#和PowerShell使用

WindowsIdentity.GetCurrent()
是库中的一个函数

WindowsPrincipal
是一种对象类型,例如
string
int

调用
WindowsIdentity.GetCurrent()
返回一个
WindowsIdentity
对象,然后可以在代码中使用该对象

由于
WindowsIdentity
不一定是要使用的对象类型,因此我们希望使用
WindowsPrincipal
对象。不幸的是,我们不能直接从
WindowsIdentity
转换到
WindowsPrincipal
对象。我们必须使用
WindowsPrincipal
构造函数

在PowerShell中,可以通过
new object
cmdlet创建新对象,也可以通过首次使用变量来创建新对象。这一便利性是因为PowerShell是一种脚本编写语言,其中使用变量(例如
$a=1
隐式创建新变量)。e、 g

PS C:\> Get-Variable test
Get-Variable : Cannot find a variable with the name 'test'.
At line:1 char:1
+ Get-Variable test
+ ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (test:String) [Get-Variable], ItemNotFoundException
    + FullyQualifiedErrorId : VariableNotFound,Microsoft.PowerShell.Commands.GetVariableCommand

PS C:\> $test = 1
PS C:\> Get-Variable test

Name                           Value
----                           -----
test                           1
使用
新对象
示例:

New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
这是正确的做法。您正在创建类型为
WindowsPrincipal
的新对象,并将Windows标识传递给构造函数

第二种方法:

[Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()
是“错误”的,因为它使用强制转换,前面我们说过不能直接从
WindowsIdentity
强制转换到
WindowsPrincipal
对象。那么这是如何工作的呢?好吧,我之前说过PowerShell会变魔术,我马上就讲。首先让我们看看正确的C代码:

在C#中调用.NET Framework特定函数的语法与PowerShell不同。您得到的特定编译错误的原因是因为我们试图强制转换对象,但我们不能

例如:

using System.Security.Principal;
var wp = WindowsIdentity.GetCurrent() as WindowsPrincipal; // compile error
编译器将其转换为:

WindowsIdentity.GetCurrent()
WindowsIdentity.GetCurrent()
WindowsIdentity.GetCurrent()
运行函数
GetCurrent()


预期返回类型为
WindowsPrincipal
谢谢您的回答。请原谅我对这个问题的错误描述。英语不是我的母语。我的问题是关于第二个PowerShell脚本,它使用的类型转换在C#中不起作用。我正在努力改进对我的问题的描述。我希望现在更容易理解。请看我的(繁重的)编辑。我误解了他们的提问,意识到问题在于PowerShell和C#如何处理类型转换。
(WindowsPrincipal) WindowsIdentity.GetCurrent();
var wp = new WindowsPrincipal(WindowsIdentity.GetCurrent());
WindowsIdentity.GetCurrent()
new WindowsPrincipal(WindowsIdentity.GetCurrent())
[Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()