Могу ли я написать класс с использованием powershell? - PullRequest
44 голосов
/ 27 июля 2011

Я все еще изучаю PowerShell, и до сих пор не нашел ответа на этом сайте, несмотря на несколько поисков.Могу ли я написать собственный пользовательский класс с помощью Powershell, создавая Powershell поверх платформы .NET?Я хочу написать свои собственные классы, используя сценарии powershell.Возможный?Пока что мои исследования заставляют меня сказать, что это невозможно.Но я хочу подтвердить это первым гуру ...

Ответы [ 3 ]

49 голосов
/ 27 июля 2011

Взгляните на Add-Type командлет. Это позволяет вам писать C # и другой код в PowerShell. Например (из приведенной выше ссылки),

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)
44 голосов
/ 27 июля 2011

Я подозреваю, что решение, которое вы ищете, это Модули Powershell .Они выполняют роли, которые классы обычно выполняют на других языках.Они дают вам очень простой, но структурированный способ повторного использования вашего кода.

Вот как получить функциональность классов в 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

Как вы видите, умножение является приватным внутри модуля.В более традиционном случае вы бы инициализировали объект, который является экземпляром модуля.Это делается с помощью параметра -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

Папка Modules в папке установки Powershell является волшебной папкой, и все хранимые там модуливидимый для командлета Import-Module без указания пути.Теперь, если мы запустим 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
24 голосов
/ 24 февраля 2015

Вы можете использовать ключевое слово class , которое было введено в PowerShell 5.0

Вот пример Тревора Салливана . (Архив здесь .)

##################################################
####### 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 Pro.

Тест драйв это так:

# 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...