PowerShell與.NET框架之間的點連接
Windows PowerShell***的功能之一就是它對.NET對象模式的直接訪問。不幸的是,由于我不是開發人員,且大部分編程概念對我來說也很陌生,這是我在學習PowerShell時***的障礙。
在我最初用PowerShell工作時,我不知道類別、端口、構造或成員的不同,對對象的概念(來自一個程序員的觀點)也不是真得了解。但我確實認為這些概念對學習和使用有Windows PowerShell的.NET很重要。我還發現,了解一些C#(或至少能讀懂它)也非常有幫助。
因此,我將試著通過舉例來簡短地解釋下這些概念并在這個過程中提供一些代碼來幫助你。我還會試著(用我有限的能力)來提供一些C# PowerShell轉換的基本指導。
讓我們從定義開始。此外,如果你是一個開發人員,對于我接下來說的所有事情都請隨意發表意見。這些定義都是我對于這些概念推導出來的意見。
.NET:它是有黑箱代碼的架構,這些代碼接受特定的輸入并返回一個值或對象。基本上,微軟為你完成了所有編碼——你只須要正確調用它。MSDN是.NET架構的無價資源。
類別(Class):我在.NET中提及的幾乎所有事情都是一個類別。我傾向于認為一個類別是一個樣板,示范對象應該是什么樣子和它應該有什么特性和類函數。舉例來說,一個Microsoft.Win32.RegistryKey對象應該有命名特性和GetValue方法。
成員(Member):每個類別都有成員,它們是連結起來的特性和類函數。如果你只想看看一個類別必須提供物的概況,這會是個好地方。
特性(Property):特性是類別兩類成員之一。簡言之,可以認為它們是對象的屬性。舉例來說,Microsoft.Win32.RegistryKey類別有Name、SubKeyCount和Value Count等特性,所以每個Microsoft.Win32.RegistryKey對象都能有這些特性。
類函數(Method):類函數是類別兩類成員之一。和特性一樣,類函數也由類別限制,但是和屬性相反,它們更像類別的功能。Microsoft.Win32.RegistryKey類別有CreateSubKey、DeleteSubkey、SetValue等類函數。和特性一樣,每個Microsoft.Win32.RegistryKey對象都能有這些類函數。
構造函數(Constructor):構造函數是類別的一個類函數,它收集創建一個類別實例所需的信息。我更喜歡將構造定義為使對象有用所需的信息或對象。用System.Data.SqlClient.SqlCommand來舉例,有四個不同方法可以讓你從該類中創建一個對象。每一方法創建出的對象都有些微不同的數據。
靜態域(Static field):它們和特性相似,但無須創建對象實例就可以獲得。在PowerShell中,訪問靜態成員確實簡單。你所要做的就是運用
[.NET Class]::StaticField。
在接下來的例子中,.NET類別System.Math會返回PI值:
[System.Math]::PI.
靜態類函數(Static method):它們就像類函數,但無須創建對象實例就可獲得。和你訪問靜態域的方式相似,你只須運用[.NET Class]::StaticMethods。
接下來的例子中,Microsoft.Win32.RegistryKey將為一個叫做MyServer的遠程機返回Microsoft.Win32.RegistryKey對象。
[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,”MyServer”)
現在我們已經涵蓋了基本的.NET框架,讓我們詳細檢查下某些PowerShell特性,如創建類別并發現這些類別可得到哪些特性和類函數。
新對象(New-Object),創建微軟.NET框架或COM對象的實例。
接下來的例子中我會創建一個System.DirectoryServices.ActiveDirectory.DirectoryContext實例:
$Context = new-object System.DirectoryServices.ActiveDirectory.DirectoryContext("DirectoryServer",$Name)
獲取成員(Get-Member),訪問對象的特性和類函數。
接下來的例子將返回$Context對象的所有成員:
$Context | Get-Member
收集所有.NET問題
以下是工作中的.NET實例。它運用新對象、構造函數和靜態類函數返回活動目錄域控制器對象。
function Get-DC { Param($Name,$Domain) if($Name) { $Context = new-object System.DirectoryServices. ActiveDirectory.DirectoryContext("DirectoryServer",$Name)
[System.DirectoryServices.
ActiveDirectory.DomainController]
::GetDomainController($Context)
}
if($Domain)
{
$Context = new-object
System.DirectoryServices.
ActiveDirectory.DirectoryContext
("Domain",$Domain)
[System.DirectoryServices.ActiveDirectory.
DomainController]::FindAll($Context)
}
if(!$Name -and !$Domain)
{
$DCName = ([adsi]"LDAP://rootDSE")
.dnsHostname.ToString()
$Context = new-object
System.DirectoryServices.ActiveDirectory.
DirectoryContext("DirectoryServer",$DCName)
[System.DirectoryServices.ActiveDirectory.
DomainController]::GetDomainController($Context)
}
}
【編輯推薦】