我还在学习powershell,到目前为止,尽管进行了一些搜索,但我还没有在这个网站上找到答案。 由于Powershell是在.NET框架之上构建的,我可以使用Powershell编写自己的自定义类吗?
我不是在谈论实例化.NET类......那部分很简单。我想使用PowerShell脚本编写自己的自定义类。可能?到目前为止,我的研究让我说这是不可能的。但我想先和大师一起确认......
答案 0 :(得分:48)
查看Add-Type cmdlet。它允许您在PowerShell中编写C#和其他代码。 例如(来自上面的链接),
C:\PS>$source = @"
public class BasicTest
{
public static int Add(int a, int b)
{
return (a + b);
}
public int Multiply(int a, int b)
{
return (a * b);
}
}
"@
C:\PS> Add-Type -TypeDefinition $source
C:\PS> [BasicTest]::Add(4, 3)
C:\PS> $basicTestObject = New-Object BasicTest
C:\PS> $basicTestObject.Multiply(5, 2)
答案 1 :(得分:43)
我怀疑您正在寻找的解决方案是Powershell Modules。它们执行类通常在其他语言中执行的角色。它们为您提供了一种非常简单但结构化的方式来重用您的代码。
以下是如何使用模块获取PS中的类的功能。在命令行,您可以这样做:
New-Module -ScriptBlock {function add($a,$b){return $a + $b}; function multiply($a,$b){return $a * $b}; function supersecret($a,$b){return multiply $a $b}; export-modulemember -function add, supersecret}
然后你就可以:
PS C:\> add 2 4
6
PS C:\> multiply 2 4
The term 'multiply' 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 inc
luded, verify that the path is correct and try again.
At line:1 char:9
+ multiply <<<< 2 4
+ CategoryInfo : ObjectNotFound: (multiply:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
PS C:\> supersecret 2 4
8
正如您所见,multiply在模块中是私有的。传统上,您会将一个对象作为模块的实例。这是通过-AsCustomObject参数完成的:
$m = New-Module -ScriptBlock {function add($a,$b){return $a + $b}; function multiply($a,$b){return $a * $b}; function supersecret($a,$b){return multiply $a $b}; export-modulemember -function add, supersecret} -AsCustomObject
然后你可以:
PS C:\> $m.add(2,4)
6
PS C:\> $m.multiply(2,4)
Method invocation failed because [System.Management.Automation.PSCustomObject] doesn't contain a method named 'multiply'.
At line:1 char:12
+ $m.multiply <<<< (2,4)
+ CategoryInfo : InvalidOperation: (multiply:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
PS C:\> $m.supersecret(2,4)
8
这一切都演示了动态模块的使用,这意味着没有任何内容存储到磁盘中以供重用。这对于非常简单的功能来说很好。如果您希望实际能够读取代码并在将来的会话或脚本中重复使用它,但是您希望将其存储在.psm1文件中,然后将该文件存储在与文件具有相同名称(减去扩展名)的文件夹中。然后,您可以在命令行或其他脚本中将模块导入会话。
作为一个例子,假设我使用了这段代码:
function Add{
param(
$a,
$b
)
return $a + $b
}
function Multiply{
param(
$a,
$b
)
return $a + $b
}
function SuperSecret{
param(
$a,
$b
)
return Multiply $a $b
}
Export-ModuleMember -Function Add, SuperSecret
并将其保存到文件夹中名为TestModule.psm1的文件中:C:\ Windows \ System32 \ WindowsPowerShell \ v1.0 \ Modules \ TestModule
Powershell安装文件夹中的Modules文件夹是一个魔术文件夹,其中存储的所有模块对Import-Module cmdlet都是可见的,无需指定路径。现在,如果我们在命令行运行Get-Module -List
,我们会看到:
ModuleType Name ExportedCommands
---------- ---- ----------------
Script DotNet {}
Manifest FileSystem {Get-FreeDiskSpace, New-Zip, Resolve-ShortcutFile, Mount-SpecialFolder...}
Manifest IsePack {Push-CurrentFileLocation, Select-CurrentTextAsVariable, ConvertTo-Short...
Manifest PowerShellPack {New-ByteAnimationUsingKeyFrames, New-TiffBitmapEncoder, New-Viewbox, Ne...
Manifest PSCodeGen {New-Enum, New-ScriptCmdlet, New-PInvoke}
Manifest PSImageTools {Add-CropFilter, Add-RotateFlipFilter, Add-OverlayFilter, Set-ImageFilte...
Manifest PSRss {Read-Article, New-Feed, Remove-Article, Remove-Feed...}
Manifest PSSystemTools {Test-32Bit, Get-USB, Get-OSVersion, Get-MultiTouchMaximum...}
Manifest PSUserTools {Start-ProcessAsAdministrator, Get-CurrentUser, Test-IsAdministrator, Ge...
Manifest TaskScheduler {Remove-Task, Get-ScheduledTask, Stop-Task, Add-TaskTrigger...}
Manifest WPK {Get-DependencyProperty, New-ModelVisual3D, New-DiscreteVector3DKeyFrame...
Manifest AppLocker {}
Manifest BitsTransfer {}
Manifest PSDiagnostics {}
Script **TestModule** {}
Manifest TroubleshootingPack {}
Manifest Citrix.XenApp.Commands... {}
我们可以看到我们的模块已准备好导入。我们可以将它导入到会话中并使用原始文件使用它:
Import-Module TestModule
或者我们可以再次实例化一个对象:
$m = Import-Module TestModule -AsCustomObject
答案 2 :(得分:24)
您可以使用the class
keyword
这是example by Trevor Sullivan。 (已存档here。)
##################################################
####### WMF 5.0 November 2014 Preview ###########
##################################################
class Beer {
# Property: Holds the current size of the beer.
[Uint32] $Size;
# Property: Holds the name of the beer's owner.
[String] $Name;
# Constructor: Creates a new Beer object, with the specified
# size and name / owner.
Beer([UInt32] $NewSize, [String] $NewName) {
# Set the Beer size
$this.Size = $NewSize;
# Set the Beer name
$this.Name = $NewName;
}
# Method: Drink the specified amount of beer.
# Parameter: $Amount = The amount of beer to drink, as an
# unsigned 32-bit integer.
[void] Drink([UInt32] $Amount) {
try {
$this.Size = $this.Size - $Amount;
}
catch {
Write-Warning -Message 'You tried to drink more beer than was available!';
}
}
# Method: BreakGlass resets the beer size to 0.
[void] BreakGlass() {
Write-Warning -Message 'The beer glass has been broken. Resetting size to 0.';
$this.Size = 0;
}
}
这适用于Windows 10专业版。
像这样试驾:
# Create a new 33 centilitre beer, named 'Chimay'
$chimay = [Beer]::new(33, 'Chimay');
$chimay.Drink(10)
$chimay.Drink(10)
# Need more beer!
$chimay.Drink(200)
$chimay.BreakGlass()