αž˜αž»αžαž„αžΆαžš Powershell αž‡αžΆαž˜αž½αž™αžαŸ’αž“αžΆαž€αŸ‹αž˜αž·αž“αž˜αŸ‚αž“αž‡αžΆ oxymoron αž‘αŸ αžαŸ’αž‰αž»αŸ†αž’αžΆαž“αžΆαžœαžΆαŸ”

αžŸαž½αžŸαŸ’αžαžΈ αž αžΆαž”! αžαŸ’αž‰αž»αŸ†αžŸαžΌαž˜αž”αž„αŸ’αž αžΆαž‰αž‡αžΌαž“αž’αŸ’αž“αž€αž“αžΌαžœαž€αžΆαžšαž”αž€αž”αŸ’αžšαŸ‚αž’αžαŸ’αžαž”αž‘ "αž˜αž»αžαž„αžΆαžš PowerShell αž‡αžΆαž˜αž½αž™αžαŸ’αž“αžΆαž€αŸ‹αŸ”
αžαŸ’αž‰αž»αŸ†β€‹αžŸαž“αŸ’αž™αžΆβ€‹αžαžΆβ€‹αžœαžΆβ€‹αž˜αž·αž“β€‹αž˜αŸ‚αž“β€‹αž‡αžΆ oxymoron"
αžŠαŸ„αž™ Christopher KuechαŸ”

αž‚αŸ†αžšαžΌαž“αŸƒαž€αžΆαžšαžŸαžšαžŸαŸαžšαž€αž˜αŸ’αž˜αžœαž·αž’αžΈαžαž˜αŸ’αžšαž„αŸ‹αž‘αž·αžŸαžœαžαŸ’αžαž» αž“αž·αž„αž˜αž»αžαž„αžΆαžšαž’αžΆαž…αž αžΆαž€αŸ‹αžŠαžΌαž…αž‡αžΆαž˜αžΆαž“αž‡αž˜αŸ’αž›αŸ„αŸ‡αž‚αŸ’αž“αžΆαž‘αŸ…αžœαž·αž‰αž‘αŸ…αž˜αž€ αž”αŸ‰αž»αž“αŸ’αžαŸ‚αž‘αžΆαŸ†αž„αž–αžΈαžšαžαŸ’αžšαžΌαžœαž”αžΆαž“αž‚αžΆαŸ†αž‘αŸ’αžšαžŸαŸ’αž˜αžΎαž‚αŸ’αž“αžΆαž“αŸ…αž€αŸ’αž“αž»αž„ Powershell αŸ” αžŸαŸ’αž‘αžΎαžšαžαŸ‚αž‚αŸ’αžšαž”αŸ‹αž—αžΆαžŸαžΆαžŸαžšαžŸαŸαžšαž€αž˜αŸ’αž˜αžœαž·αž’αžΈαž‘αžΆαŸ†αž„αž’αžŸαŸ‹ αž˜αžΆαž“αž˜αž»αžαž„αžΆαžš αž¬αž’αžαŸ‹ αž˜αžΆαž“αž€αž“αŸ’αž›αŸ‚αž„αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž—αŸ’αž‡αžΆαž”αŸ‹αžαž˜αŸ’αž›αŸƒαžˆαŸ’αž˜αŸ„αŸ‡αž”αž“αŸ’αžαŸ‚αž˜αŸ” αžαŸ’αž“αžΆαž€αŸ‹ αžŠαžΌαž…αž‡αžΆαžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’ αž“αž·αž„αž€αŸ†αžŽαžαŸ‹αžαŸ’αžšαžΆ αž‚αŸ’αžšαžΆαž“αŸ‹αžαŸ‚αž‡αžΆαžœαž·αž’αžΈαžŸαžΆαžŸαŸ’αžšαŸ’αžαž˜αž½αž™αŸ” αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž™αžΎαž„αž€αŸ†αžŽαžαŸ‹αž€αžΆαžšαž”αŸ’αžšαžΎαž”αŸ’αžšαžΆαžŸαŸ‹ Classes αžšαž”αžŸαŸ‹αž™αžΎαž„αž‘αŸ…αž“αžΉαž„αž€αžΆαžšαž…αž„αž“αŸƒαžˆαŸ’αž˜αŸ„αŸ‡ αž“αž·αž„αžαž˜αŸ’αž›αŸƒ αž αžΎαž™αž‡αŸ€αžŸαžœαžΆαž„αž€αžΆαžšαžŸαžšαžŸαŸαžšαž€αž˜αŸ’αž˜αžœαž·αž’αžΈαžŠαŸ‚αž›αžαž˜αŸ’αžšαž„αŸ‹αž‘αž·αžŸαžœαžαŸ’αžαž»αž’αŸ’αž„αž“αŸ‹αŸ—αžŠαžΌαž…αž‡αžΆ inheritance, polymorphism ឬ mutability αž“αŸ„αŸ‡αž™αžΎαž„αž’αžΆαž…αž‘αžΆαž‰αž™αž€αž’αžαŸ’αžαž”αŸ’αžšαž™αŸ„αž‡αž“αŸαž–αžΈαž’αžαŸ’αžαž”αŸ’αžšαž™αŸ„αž‡αž“αŸαžšαž”αžŸαŸ‹αžœαžΆαžŠαŸ„αž™αž˜αž·αž“αž’αŸ’αžœαžΎαž’αŸ„αž™αž€αžΌαžŠαžšαž”αžŸαŸ‹αž™αžΎαž„αž˜αžΆαž“αž—αžΆαž–αžŸαŸ’αž˜αž»αž‚αžŸαŸ’αž˜αžΆαž‰αŸ” αž›αžΎαžŸαž–αžΈαž“αŸαŸ‡ αžαžΆαž˜αžšαž™αŸˆαž€αžΆαžšαž”αž“αŸ’αžαŸ‚αž˜αžœαž·αž’αžΈαžŸαžΆαžŸαŸ’αžαŸ’αžšαž”αŸ†αž”αŸ’αž›αŸ‚αž„αž”αŸ’αžšαž—αŸαž‘αžŠαŸ‚αž›αž˜αž·αž“αž’αžΆαž…αž€αŸ‚αž”αŸ’αžšαŸ‚αž”αžΆαž“ αž™αžΎαž„αž’αžΆαž…αž–αž„αŸ’αžšαžΉαž„αž€αžΌαžŠαž˜αž»αžαž„αžΆαžšαžšαž”αžŸαŸ‹αž™αžΎαž„αž‡αžΆαž˜αž½αž™αž“αžΉαž„ ClassesαŸ”

αžœαŸαž‘αž˜αž“αŸ’αžαž“αŸƒαžœαžŽαŸ’αžŽαŸˆ

Castes αž‚αžΊαž‡αžΆαž˜αž»αžαž„αžΆαžšαžŠαŸαž˜αžΆαž“αž₯αž‘αŸ’αž’αž·αž–αž›αž”αŸ†αž•αž»αžαž˜αž½αž™αž“αŸ…αž€αŸ’αž“αž»αž„ PowershellαŸ” αž“αŸ…αž–αŸαž›αž’αŸ’αž“αž€αž”αŸ„αŸ‡αžαž˜αŸ’αž›αŸƒ αž’αŸ’αž“αž€αž€αŸ†αž–αž»αž„αž–αžΉαž„αž•αŸ’αž’αŸ‚αž€αž›αžΎαž€αžΆαžšαž…αžΆαž”αŸ‹αž•αŸ’αžαžΎαž˜ αž“αž·αž„αžŸαž˜αžαŸ’αžαž—αžΆαž–αž”αž‰αŸ’αž‡αžΆαž€αŸ‹αžŠαŸ„αž™αž”αž„αŸ’αž€αž”αŸ‹αž“αŸαž™ αžŠαŸ‚αž›αž”αžšαž·αžŸαŸ’αžαžΆαž“αž”αž“αŸ’αžαŸ‚αž˜αž‘αŸ…αž€αž˜αŸ’αž˜αžœαž·αž’αžΈαžšαž”αžŸαŸ‹αž’αŸ’αž“αž€αŸ” αž§αž‘αžΆαž αžšαžŽαŸ αž€αžΆαžšβ€‹αž”αž‰αŸ’αž…αžΌαž›β€‹αžαŸ’αžŸαŸ‚αž’αž€αŸ’αžŸαžšβ€‹αž€αŸ’αž“αž»αž„ [xml] αž“αžΉαž„β€‹αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšβ€‹αžœαžΆβ€‹αžαžΆαž˜β€‹αžšαž™αŸˆβ€‹αž€αžΌαžŠβ€‹αž‰αŸ‚αž€ αž αžΎαž™β€‹αž”αž„αŸ’αž€αžΎαžβ€‹αž˜αŸ‚αž€αž’αžΆαž„ xml αž–αŸαž‰αž›αŸαž‰αŸ” αž™αžΎαž„αž’αžΆαž…αž”αŸ’αžšαžΎ Classes αž€αŸ’αž“αž»αž„αž€αžΌαžŠαžšαž”αžŸαŸ‹αž™αžΎαž„αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž‚αŸ„αž›αž”αŸ†αžŽαž„αžŠαžΌαž…αž‚αŸ’αž“αžΆαŸ”

ខអស hashables

αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž’αŸ’αž“αž€αž˜αž·αž“αž˜αžΆαž“ constructor αž’αŸ’αž“αž€αž’αžΆαž…αž”αž“αŸ’αžαžŠαŸ„αž™αž‚αŸ’αž˜αžΆαž“αž˜αž½αž™αžŠαŸ„αž™αžŠαžΆαž€αŸ‹ hashable αž‘αŸ…αž”αŸ’αžšαž—αŸαž‘ class αžšαž”αžŸαŸ‹αž’αŸ’αž“αž€αŸ” αž€αž»αŸ†αž—αŸ’αž›αŸαž…αž”αŸ’αžšαžΎαž‚αž»αžŽαž›αž€αŸ’αžαžŽαŸˆαžŸαž»αž–αž›αž—αžΆαž– αžŠαžΎαž˜αŸ’αž”αžΈαž‘αžΆαž‰αž™αž€αž’αžαŸ’αžαž”αŸ’αžšαž™αŸ„αž‡αž“αŸαž–αŸαž‰αž›αŸαž‰αž–αžΈαž‚αŸ†αžšαžΌαž“αŸαŸ‡αŸ” αž€αŸ’αž“αž»αž„αž–αŸαž›αž‡αžΆαž˜αž½αž™αž‚αŸ’αž“αžΆαž“αŸαŸ‡ αž™αžΎαž„αž’αžΆαž…αž”αŸ’αžšαžΎαž›αž€αŸ’αžαžŽαžŸαž˜αŸ’αž”αžαŸ’αžαž·αžŠαŸ‚αž›αž”αžΆαž“αžœαžΆαž™αž”αž‰αŸ’αž…αžΌαž›αžšαž”αžŸαŸ‹αžαŸ’αž“αžΆαž€αŸ‹ αžŠαžΎαž˜αŸ’αž”αžΈαžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαžŸαžΌαž˜αŸ’αž”αžΈαžαŸ‚αž€αžΆαžšαž…αžΆαž”αŸ‹αž•αŸ’αžαžΎαž˜ αž“αž·αž„αžαž€αŸ’αž€αžœαž·αž‡αŸ’αž‡αžΆαžŸαž»αž–αž›αž—αžΆαž–αž€αžΆαž“αŸ‹αžαŸ‚αžŸαŸŠαžΈαž‡αž˜αŸ’αžšαŸ…αŸ”

class Cluster {
    [ValidatePattern("^[A-z]+$")]
    [string] $Service
    [ValidateSet("TEST", "STAGE", "CANARY", "PROD")]
    [string] $FlightingRing
    [ValidateSet("EastUS", "WestUS", "NorthEurope")]
    [string] $Region
    [ValidateRange(0, 255)]
    [int] $Index
}

[Cluster]@{
    Service       = "MyService"
    FlightingRing = "PROD"
    Region        = "EastUS"
    Index         = 2
}

αž›αžΎαžŸαž–αžΈαž“αŸαŸ‡αž‘αŸ€αžαž€αžΆαžšαžαžΆαžŸαž‡αž½αž™αž±αŸ’αž™αž‘αž‘αž½αž›αž”αžΆαž“αž›αž‘αŸ’αž’αž•αž›αžŸαŸ’αž’αžΆαžαŸ” αž”αŸ’αžšαŸ€αž”αž’αŸ€αž”αž›αž‘αŸ’αž’αž•αž›αž“αŸƒ Cluster hashtable array αžŠαŸ‚αž›αž”αžΆαž“αž”αž‰αŸ’αž‡αžΌαž“αž‘αŸ…αž€αžΆαž“αŸ‹ Format-Table αž‡αžΆαž˜αž½αž™αž“αžΉαž„αž’αŸ’αžœαžΈαžŠαŸ‚αž›αž’αŸ’αž“αž€αž‘αž‘αž½αž›αž”αžΆαž“ αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž’αŸ’αž“αž€αž”αŸ„αŸ‡ hashtables αž‘αžΆαŸ†αž„αž“αŸαŸ‡αž‡αžΆαž›αžΎαž€αžŠαŸ†αž”αžΌαž„αž‘αŸ…αž€αŸ’αž“αž»αž„αžαŸ’αž“αžΆαž€αŸ‹αž˜αž½αž™αŸ” αž›αž€αŸ’αžαžŽαžŸαž˜αŸ’αž”αžαŸ’αžαž·αž“αŸƒαžαŸ’αž“αžΆαž€αŸ‹αžαŸ‚αž„αžαŸ‚αžαŸ’αžšαžΌαžœαž”αžΆαž“αžšαžΆαž™αž€αŸ’αž“αž»αž„αž›αŸ†αžŠαžΆαž”αŸ‹αžŠαŸ‚αž›αž–αž½αž€αžœαžΆαžαŸ’αžšαžΌαžœαž”αžΆαž“αž€αŸ†αžŽαžαŸ‹αž“αŸ…αž‘αžΈαž“αŸ„αŸ‡αŸ” αž€αž»αŸ†αž—αŸ’αž›αŸαž…αž”αž“αŸ’αžαŸ‚αž˜αž–αžΆαž€αŸ’αž™αž‚αž“αŸ’αž›αžΉαŸ‡αžŠαŸ‚αž›αž›αžΆαž€αŸ‹αž˜αž»αž“αž›αž€αŸ’αžαžŽαŸˆαžŸαž˜αŸ’αž”αžαŸ’αžαž·αž‘αžΆαŸ†αž„αž’αžŸαŸ‹αžŠαŸ‚αž›αž’αŸ’αž“αž€αž˜αž·αž“αž…αž„αŸ‹αžƒαžΎαž‰αž“αŸ…αž€αŸ’αž“αž»αž„αž›αž‘αŸ’αž’αž•αž›αŸ”

αž˜αž»αžαž„αžΆαžš Powershell αž‡αžΆαž˜αž½αž™αžαŸ’αž“αžΆαž€αŸ‹αž˜αž·αž“αž˜αŸ‚αž“αž‡αžΆ oxymoron αž‘αŸ αžαŸ’αž‰αž»αŸ†αž’αžΆαž“αžΆαžœαžΆαŸ”

αž€αžΆαžšαž”αž‰αŸ’αž…αŸαž‰αž’αžαŸ’αžαž“αŸαž™

αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž’αŸ’αž“αž€αž˜αžΆαž“ constructor αžŠαŸ‚αž›αž˜αžΆαž“αž’αžΆαž‚αž»αž™αž˜αŸ‰αž„αŸ‹αž˜αž½αž™ αž€αžΆαžšαž”αž‰αŸ’αž‡αžΌαž“αžαž˜αŸ’αž›αŸƒαž‘αŸ…αž”αŸ’αžšαž—αŸαž‘ class αžšαž”αžŸαŸ‹αž’αŸ’αž“αž€αž“αžΉαž„αž”αž‰αŸ’αž‡αžΌαž“αžαž˜αŸ’αž›αŸƒαž‘αŸ… constructor αžšαž”αžŸαŸ‹αž’αŸ’αž“αž€ αžŠαŸ‚αž›αž‡αžΆαž€αž“αŸ’αž›αŸ‚αž„αžŠαŸ‚αž›αž’αŸ’αž“αž€αž’αžΆαž…αž…αžΆαž”αŸ‹αž•αŸ’αžαžΎαž˜ instance αž“αŸƒ class αžšαž”αžŸαŸ‹αž’αŸ’αž“αž€αŸ”

class Cluster {
    [ValidatePattern("^[A-z]+$")]
    [string] $Service
    [ValidateSet("TEST", "STAGE", "CANARY", "PROD")]
    [string] $FlightingRing
    [ValidateSet("EastUS", "WestUS", "NorthEurope")]
    [string] $Region
    [ValidateRange(0, 255)]
    [int] $Index

    Cluster([string] $id) {
        $this.Service, $this.FlightingRing, $this.Region, $this.Index = $id -split "-"
    }
}

[Cluster]"MyService-PROD-EastUS-2"

αž”αŸ„αŸ‡αž‘αŸ…αž”αž“αŸ’αž‘αžΆαžαŸ‹

αž’αŸ’αž“αž€αž€αŸαž’αžΆαž…αž”αžŠαž·αžŸαŸαž’αžœαž·αž’αžΈαžŸαžΆαžŸαŸ’αžαŸ’αžšαžαŸ’αž“αžΆαž€αŸ‹ [string] ToString() αžŠαžΎαž˜αŸ’αž”αžΈαž€αŸ†αžŽαžαŸ‹αžαž€αŸ’αž€αžœαž·αž‡αŸ’αž‡αžΆαž“αŸ…αž–αžΈαž€αŸ’αžšαŸ„αž™αž€αžΆαžšαžαŸ†αžŽαžΆαž„αžαŸ’αžŸαŸ‚αž’αž€αŸ’αžŸαžšαžšαž”αžŸαŸ‹αžœαžαŸ’αžαž» αžŠαžΌαž…αž‡αžΆαž€αžΆαžšαž”αŸ’αžšαžΎαž€αžΆαžšαž”αž‰αŸ’αž…αžΌαž›αžαŸ’αžŸαŸ‚αž’αž€αŸ’αžŸαžšαž‡αžΆαžŠαžΎαž˜αŸ”

class Cluster {
    [ValidatePattern("^[A-z]+$")]
    [string] $Service
    [ValidateSet("TEST", "STAGE", "CANARY", "PROD")]
    [string] $FlightingRing
    [ValidateSet("EastUS", "WestUS", "NorthEurope")]
    [string] $Region
    [ValidateRange(0, 255)]
    [int] $Index

    [string] ToString() {
        return $this.Service, $this.FlightingRing, $this.Region, $this.Index -join "-"
    }
}

$cluster = [Cluster]@{
    Service       = "MyService"
    FlightingRing = "PROD"
    Region        = "EastUS"
    Index         = 2
}

Write-Host "We just created a model for '$cluster'"

αžαžΆαžŸαž€αžšαžŽαžΈαžŠαŸ‚αž›αž‡αžΆαž”αŸ‹αž‡αžΆαžŸαŸŠαŸαžšαžΈ

Cast αž’αž“αž»αž‰αŸ’αž‰αžΆαžαž±αŸ’αž™αž˜αžΆαž“αž€αžΆαžšαž”αž“αŸ’αžŸαžΆαž”αžŠαŸ„αž™αžŸαž»αžœαžαŸ’αžαž·αž—αžΆαž–αŸ” αž§αž‘αžΆαž αžšαžŽαŸαžαžΆαž„αž€αŸ’αžšαŸ„αž˜αž“αžΉαž„αž”αžšαžΆαž‡αŸαž™ αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž‘αž·αž“αŸ’αž“αž“αŸαž™αž˜αž·αž“αž”αŸ†αž–αŸαž‰αžαžΆαž˜αž€αžΆαžšαž”αž‰αŸ’αž‡αžΆαž€αŸ‹αžšαž”αžŸαŸ‹αž™αžΎαž„αž“αŸ…αž€αŸ’αž“αž»αž„ Cluster

# Валидация сСриализованных Π΄Π°Π½Π½Ρ‹Ρ…

[Cluster]$cluster = Get-Content "./my-cluster.json" | ConvertFrom-Json
[Cluster[]]$clusters = Import-Csv "./my-clusters.csv"

Castes αž“αŸ…αž€αŸ’αž“αž»αž„αž€αžΌαžŠαž˜αž»αžαž„αžΆαžšαžšαž”αžŸαŸ‹αž’αŸ’αž“αž€αŸ”

αž€αž˜αŸ’αž˜αžœαž·αž’αžΈαž˜αž»αžαž„αžΆαžšαžŠαŸ†αž”αžΌαž„αž€αŸ†αžŽαžαŸ‹αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αž‘αž·αž“αŸ’αž“αž“αŸαž™ αž”αž“αŸ’αž‘αžΆαž”αŸ‹αž˜αž€αž’αž“αž»αžœαžαŸ’αžαž€αž˜αŸ’αž˜αžœαž·αž’αžΈαž‡αžΆαž›αŸ†αžŠαžΆαž”αŸ‹αž“αŸƒαž€αžΆαžšαž•αŸ’αž›αžΆαžŸαŸ‹αž”αŸ’αžαžΌαžšαž›αžΎαžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αž‘αž·αž“αŸ’αž“αž“αŸαž™αžŠαŸ‚αž›αž˜αž·αž“αž’αžΆαž…αž•αŸ’αž›αžΆαžŸαŸ‹αž”αŸ’αžαžΌαžšαž”αžΆαž“αŸ” αž‘αŸ„αŸ‡αž”αžΈαž‡αžΆαž˜αžΆαž“αž€αžΆαžšαž…αžΆαž”αŸ‹αž’αžΆαžšαž˜αŸ’αž˜αžŽαŸαž•αŸ’αž‘αž»αž™αž‚αŸ’αž“αžΆαž€αŸαžŠαŸ„αž™ αžαŸ’αž“αžΆαž€αŸ‹αž–αž·αžαž‡αžΆαž‡αž½αž™αž’αŸ’αž“αž€αž€αŸ’αž“αž»αž„αž€αžΆαžšαžŸαžšαžŸαŸαžšαž€αžΌαžŠαž˜αž»αžαž„αžΆαžš αž’αžšαž‚αž»αžŽαž…αŸ†αž–αŸ„αŸ‡αž€αžΆαžšαžœαžΆαž™αž”αž‰αŸ’αž…αžΌαž›αžœαž·αž’αžΈαžŸαžΆαžŸαŸ’αžαŸ’αžšαž”αŸ†αž”αŸ’αž›αŸ‚αž„αŸ”

តើ Powershell αžŠαŸ‚αž›αžαŸ’αž‰αž»αŸ†αž€αŸ†αž–αž»αž„αžŸαžšαžŸαŸαžšαž˜αžΆαž“αž˜αž»αžαž„αžΆαžšαž‘αŸ?

αž˜αž“αž»αžŸαŸ’αžŸαž‡αžΆαž…αŸ’αžšαžΎαž“αžŠαŸ‚αž›αž˜αž€αž–αžΈ C# αž¬αž•αŸ’αž‘αŸƒαžαžΆαž„αž€αŸ’αžšαŸ„αž™αžŸαŸ’αžšαžŠαŸ€αž„αž‚αŸ’αž“αžΆαž€αŸ†αž–αž»αž„αžŸαžšαžŸαŸαžš Powershell αžŠαŸ‚αž›αžŸαŸ’αžšαžŠαŸ€αž„αž“αžΉαž„ C# αŸ” αžαžΆαž˜αžšαž™αŸˆαž€αžΆαžšαž’αŸ’αžœαžΎαžŠαžΌαž…αž“αŸαŸ‡ αž’αŸ’αž“αž€αž€αŸ†αž–αž»αž„αž„αžΆαž€αž…αŸαž‰αž–αžΈαž€αžΆαžšαž”αŸ’αžšαžΎαž”αŸ’αžšαžΆαžŸαŸ‹αž‚αŸ†αž“αž·αžαž€αž˜αŸ’αž˜αžœαž·αž’αžΈαž˜αž»αžαž„αžΆαžš αž αžΎαž™αž‘αŸ†αž“αž„αž‡αžΆαž“αžΉαž„αž‘αž‘αž½αž›αž”αžΆαž“αž’αžαŸ’αžαž”αŸ’αžšαž™αŸ„αž‡αž“αŸαž–αžΈαž€αžΆαžšαž‡αŸ’αžšαž˜αž»αž‡αž‘αžΉαž€αž™αŸ‰αžΆαž„αžαŸ’αž›αžΆαŸ†αž„αž‘αŸ…αž€αŸ’αž“αž»αž„αž€αž˜αŸ’αž˜αžœαž·αž’αžΈαžαž˜αŸ’αžšαž„αŸ‹αž‘αž·αžŸαžœαžαŸ’αžαž»αž“αŸ…αž€αŸ’αž“αž»αž„ Powershell αž¬αžŸαŸ’αžœαŸ‚αž„αž™αž›αŸ‹αž”αž“αŸ’αžαŸ‚αž˜αž’αŸ†αž–αžΈαž€αžΆαžšαžŸαžšαžŸαŸαžšαž€αž˜αŸ’αž˜αžœαž·αž’αžΈαž˜αž»αžαž„αžΆαžšαŸ”

αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž’αŸ’αž“αž€αž–αžΉαž„αž•αŸ’αž’αŸ‚αž€αžαŸ’αž›αžΆαŸ†αž„αž›αžΎαž€αžΆαžšαž”αŸ†αž”αŸ’αž›αŸ‚αž„αž‘αž·αž“αŸ’αž“αž“αŸαž™αžŠαŸ‚αž›αž˜αž·αž“αž’αžΆαž…αž•αŸ’αž›αžΆαžŸαŸ‹αž”αŸ’αžαžΌαžšαž”αžΆαž“αžŠαŸ„αž™αž”αŸ’αžšαžΎαž”αŸ†αž–αž„αŸ‹ (|), Where-Object, ForEach-Object, Select-Object, Group-Object, Sort-Object αŸ”αž›αŸ” αžαŸ’αž“αžΆαž€αŸ‹αž“αŸ…αž€αŸ’αž“αž»αž„αžšαž…αž“αžΆαž”αŸαž‘αŸ’αž˜αž˜αž»αžαž„αžΆαžšαŸ”

αž€αžΆαžšαž”αŸ’αžšαžΎαž”αŸ’αžšαžΆαžŸαŸ‹αž˜αž»αžαž„αžΆαžšαž“αŸƒαžαŸ’αž“αžΆαž€αŸ‹

αžœαžŽαŸ’αžŽαŸˆ αž‘αŸ„αŸ‡αž”αžΈαž‡αžΆαž–αž½αž€αž‚αŸαž”αŸ’αžšαžΎαžœαžΆαž€αŸ’αž™αžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αž‡αŸ†αž“αž½αžŸαž€αŸαžŠαŸ„αž™ αž‚αžΊαž‚αŸ’αžšαžΆαž“αŸ‹αžαŸ‚αž‡αžΆαž€αžΆαžšαž‚αžΌαžŸαž•αŸ‚αž“αž‘αžΈαžšαžœαžΆαž„αžŠαŸ‚αž“αž–αžΈαžšαž”αŸ‰αž»αžŽαŸ’αžŽαŸ„αŸ‡αŸ” αž“αŸ…αž€αŸ’αž“αž»αž„αž”αŸ†αž–αž„αŸ‹αž”αž„αŸ’αž αžΌαžš αž’αŸ’αž“αž€αž’αžΆαž…αž‚αžΌαžŸαž•αŸ‚αž“αž‘αžΈαž’αžΆαžšαŸαž“αŸƒαžαž˜αŸ’αž›αŸƒαžŠαŸ„αž™αž”αŸ’αžšαžΎ ForEach-Object αŸ”

αž€αŸ’αž“αž»αž„αž§αž‘αžΆαž αžšαžŽαŸαžαžΆαž„αž€αŸ’αžšαŸ„αž˜ Node constructor αžαŸ’αžšαžΌαžœαž”αžΆαž“αž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·αžšαžΆαž›αŸ‹αž–αŸαž›αžŠαŸ‚αž› Datum αžαŸ’αžšαžΌαžœαž”αžΆαž“αžŠαŸαž‰ αž αžΎαž™αž“αŸαŸ‡αž•αŸ’αžαž›αŸ‹αž±αŸ’αž™αž™αžΎαž„αž“αžΌαžœαž±αž€αžΆαžŸαžŠαžΎαž˜αŸ’αž”αžΈαž‡αŸ€αžŸαžœαžΆαž„αž€αžΆαžšαžŸαžšαžŸαŸαžšαž€αžΌαžŠαž…αŸ†αž“αž½αž“αžŸαž˜αžšαž˜αŸ’αž™αŸ” αž‡αžΆαž›αž‘αŸ’αž’αž•αž› αž”αŸ†αž–αž„αŸ‹αž”αž„αŸ’αž αžΌαžšαž”αŸ’αžšαŸαž„αžšαž”αžŸαŸ‹αž™αžΎαž„αž•αŸ’αžαŸ„αžαž›αžΎαž€αžΆαžšαžŸαžΆαž€αžŸαž½αžšαž‘αž·αž“αŸ’αž“αž“αŸαž™ αž“αž·αž„αž€αžΆαžšαž”αŸ’αžšαž˜αžΌαž›αž•αŸ’αžαž»αŸ†αžŠαŸ„αž™αž”αŸ’αžšαž€αžΆαžŸ αžαžŽαŸˆαžŠαŸ‚αž›αžαŸ’αž“αžΆαž€αŸ‹αžšαž”αžŸαŸ‹αž™αžΎαž„αž™αž€αž…αž·αžαŸ’αžαž‘αž»αž€αžŠαžΆαž€αŸ‹αž›αžΎαž€αžΆαžšαžœαž·αž—αžΆαž‚αž‘αž·αž“αŸ’αž“αž“αŸαž™ αž“αž·αž„αžŸαž»αž–αž›αž—αžΆαž–αŸ”

# ΠŸΡ€ΠΈΠΌΠ΅Ρ€ комбинирования классов с ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π°ΠΌΠΈ для separation of concerns Π² ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π°Ρ…

class Node {
    [ValidateLength(3, 7)]
    [string] $Name
    [ValidateSet("INT", "PPE", "PROD")]
    [string] $FlightingRing
    [ValidateSet("EastUS", "WestUS", "NorthEurope", "WestEurope")]
    [string] $Region
    Node([string] $Name) {
        $Name -match "([a-z]+)(INT|PPE|PROD)([a-z]+)"
        $_, $this.Service, $this.FlightingRing, $this.Region = $Matches
        $this.Name = $Name
    }
}

class Datum {
    [string] $Name
    [int] $Value
    [Node] $Computer
    [int] Severity() {
        $this.Name -match "[0-9]+$"
        return $Matches[0]
    }
}

Write-Host "Urgent Security Audit Issues:"
Import-Csv "./audit-results.csv" `
    | ForEach-Object {[Datum]$_} `
    | Where-Object Value -gt 0 `
    | Group-Object {$_.Severity()} `
    | Where-Object Name -lt 2 `
    | ForEach-Object Group `
    | ForEach-Object Computer `
    | Where-Object FlightingRing -eq "PROD" `
    | Sort-Object Name, Region -Unique

αžαŸ’αž“αžΆαž€αŸ‹αžœαŸαž…αžαŸ’αž…αž”αŸ‹αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž”αŸ’αžšαžΎαž‘αžΎαž„αžœαž·αž‰

αž‚αŸ’αž˜αžΆαž“αž’αŸ’αžœαžΈαž›αŸ’αž’αžŠαžΌαž…αžŠαŸ‚αž›αžœαžΆαž αžΆαž€αŸ‹αžŠαžΌαž…αž‡αžΆαž“αŸ„αŸ‡αž‘αŸαŸ”

αž‡αžΆαž’αž€αž»αžŸαž› αžαŸ’αž“αžΆαž€αŸ‹αž˜αž·αž“αž’αžΆαž…αž“αžΆαŸ†αž…αŸαž‰αžŠαŸ„αž™αž˜αŸ‰αžΌαžŒαž»αž›αžαžΆαž˜αžšαž”αŸ€αž”αžŠαžΌαž…αž‚αŸ’αž“αžΆαž“αžΉαž„αž˜αž»αžαž„αžΆαžš αž¬αž’αžαŸαžšαŸ” αž”αŸ‰αž»αž“αŸ’αžαŸ‚αž˜αžΆαž“αž›αŸ’αž”αž·αž…αž˜αž½αž™αž…αŸ†αž“αž½αž“αŸ” αž…αžΌαžšαž“αž·αž™αžΆαž™αžαžΆαžαŸ’αž“αžΆαž€αŸ‹αžšαž”αžŸαŸ‹αž’αŸ’αž“αž€αžαŸ’αžšαžΌαžœαž”αžΆαž“αž€αŸ†αžŽαžαŸ‹αž“αŸ…αž€αŸ’αž“αž»αž„αž―αž€αžŸαžΆαžš ./my-classes.ps1

  • αž’αŸ’αž“αž€αž’αžΆαž… dotsource αž―αž€αžŸαžΆαžšαž‡αžΆαž˜αž½αž™αžαŸ’αž“αžΆαž€αŸ‹αŸ–. ./my-classes.ps1. αžœαžΆαž“αžΉαž„αžŠαŸ†αžŽαžΎαžšαž€αžΆαžš my-classes.ps1 αž“αŸ…αž€αŸ’αž“αž»αž„αžœαž·αžŸαžΆαž›αž—αžΆαž–αž”αž…αŸ’αž…αž»αž”αŸ’αž”αž“αŸ’αž“αžšαž”αžŸαŸ‹αž’αŸ’αž“αž€ αž αžΎαž™αž€αŸ†αžŽαžαŸ‹αžαŸ’αž“αžΆαž€αŸ‹αž‘αžΆαŸ†αž„αž’αžŸαŸ‹αž–αžΈαž―αž€αžŸαžΆαžšαž“αŸ…αž‘αžΈαž“αŸ„αŸ‡αŸ”

  • αž’αŸ’αž“αž€αž’αžΆαž…αž”αž„αŸ’αž€αžΎαžαž˜αŸ‰αžΌαžŒαž»αž› Powershell αžŠαŸ‚αž›αž“αžΆαŸ†αž…αŸαž‰ API αž•αŸ’αž‘αžΆαž›αŸ‹αžαŸ’αž›αž½αž“αžšαž”αžŸαŸ‹αž’αŸ’αž“αž€αž‘αžΆαŸ†αž„αž’αžŸαŸ‹ (cmdlets) αž αžΎαž™αž€αŸ†αžŽαžαŸ‹αž’αžαŸαžš ScriptsToProcess = "./my-classes.ps1" αž“αŸ…αž€αŸ’αž“αž»αž„αž€αžΆαžšαž”αž„αŸ’αž αžΆαž‰αž˜αŸ‰αžΌαžŒαž»αž›αžšαž”αžŸαŸ‹αž’αŸ’αž“αž€ αž‡αžΆαž˜αž½αž™αž“αžΉαž„αž›αž‘αŸ’αž’αž•αž›αžŠαžΌαž…αž‚αŸ’αž“αžΆαŸ– ./my-classes.ps1 αž“αžΉαž„αž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·αž€αŸ’αž“αž»αž„ αž”αžšαž·αžŸαŸ’αžαžΆαž“αžšαž”αžŸαŸ‹αž’αŸ’αž“αž€αŸ”

αž‡αž˜αŸ’αžšαžΎαžŸαžŽαžΆαž˜αž½αž™αžŠαŸ‚αž›αž’αŸ’αž“αž€αž‡αŸ’αžšαžΎαžŸαžšαžΎαžŸ αžŸαžΌαž˜αž…αžΆαŸ†αžαžΆαž”αŸ’αžšαž–αŸαž“αŸ’αž’αž”αŸ’αžšαž—αŸαž‘αžšαž”αžŸαŸ‹ Powershell αž˜αž·αž“αž’αžΆαž…αžŠαŸ„αŸ‡αžŸαŸ’αžšαžΆαž™αž”αŸ’αžšαž—αŸαž‘αž“αŸƒαžˆαŸ’αž˜αŸ„αŸ‡αžŠαžΌαž…αž‚αŸ’αž“αžΆαžŠαŸ‚αž›αž”αžΆαž“αž•αŸ’αž‘αž»αž€αž–αžΈαž€αž“αŸ’αž›αŸ‚αž„αž•αŸ’αžŸαŸαž„αž‚αŸ’αž“αžΆαž“αŸ„αŸ‡αž‘αŸαŸ”
αž‘αŸ„αŸ‡αž”αžΈαž‡αžΆαž’αŸ’αž“αž€αž•αŸ’αž‘αž»αž€αžαŸ’αž“αžΆαž€αŸ‹αžŠαžΌαž…αž‚αŸ’αž“αžΆαž–αžΈαžšαžŠαŸ‚αž›αž˜αžΆαž“αž›αž€αŸ’αžαžŽαŸˆαžŸαž˜αŸ’αž”αžαŸ’αžαž·αžŠαžΌαž…αž‚αŸ’αž“αžΆαž–αžΈαž€αž“αŸ’αž›αŸ‚αž„αž•αŸ’αžŸαŸαž„αž‚αŸ’αž“αžΆαž€αŸαžŠαŸ„αž™ αž’αŸ’αž“αž€αž˜αžΆαž“αž αžΆαž“αž·αž—αŸαž™αž€αŸ’αž“αž»αž„αž€αžΆαžšαž”αŸ’αžšαžˆαž˜αž˜αž»αžαž“αžΉαž„αž”αž‰αŸ’αž αžΆαŸ”

αž•αŸ’αž›αžΌαžœαž†αŸ’αž–αŸ„αŸ‡αž‘αŸ…αž˜αž»αž

αž˜αž’αŸ’αž™αŸ„αž”αžΆαž™αžŠαŸαž›αŸ’αž’αž”αŸ†αž•αž»αžαžŠαžΎαž˜αŸ’αž”αžΈαž‡αŸ€αžŸαžœαžΆαž„αž”αž‰αŸ’αž αžΆαžŠαŸ†αžŽαŸ„αŸ‡αžŸαŸ’αžšαžΆαž™αž”αŸ’αžšαž—αŸαž‘αž‚αžΊαž€αž»αŸ†αž”αž„αŸ’αž αžΆαž‰αžαŸ’αž“αžΆαž€αŸ‹αžšαž”αžŸαŸ‹αž’αŸ’αž“αž€αžŠαž›αŸ‹αž’αŸ’αž“αž€αž”αŸ’αžšαžΎαž”αŸ’αžšαžΆαžŸαŸ‹αŸ” αž‡αŸ†αž“αž½αžŸαž±αŸ’αž™αž€αžΆαžšαžšαŸ†αž–αžΉαž„αžαžΆαž’αŸ’αž“αž€αž”αŸ’αžšαžΎαž”αŸ’αžšαžΆαžŸαŸ‹αž“αžΉαž„αž“αžΆαŸ†αž…αžΌαž›αž”αŸ’αžšαž—αŸαž‘αžŠαŸ‚αž›αž€αŸ†αžŽαžαŸ‹αžαŸ’αž“αžΆαž€αŸ‹ αž“αžΆαŸ†αž…αŸαž‰αž˜αž»αžαž„αžΆαžšαž–αžΈαž˜αŸ‰αžΌαžŒαž»αž›αžšαž”αžŸαŸ‹αž’αŸ’αž“αž€αžŠαŸ‚αž›αž›αž»αž”αž”αŸ†αž”αžΆαžαŸ‹αžαž˜αŸ’αžšαžΌαžœαž€αžΆαžšαž€αŸ’αž“αž»αž„αž€αžΆαžšαž…αžΌαž›αž”αŸ’αžšαžΎαžαŸ’αž“αžΆαž€αŸ‹αžŠαŸ„αž™αž•αŸ’αž‘αžΆαž›αŸ‹αŸ” αžŸαž˜αŸ’αžšαžΆαž”αŸ‹ Cluster αž™αžΎαž„β€‹αž’αžΆαž…β€‹αž“αžΆαŸ†αž…αŸαž‰β€‹αž˜αž»αžαž„αžΆαžš New-Cluster αžŠαŸ‚αž›β€‹αž“αžΉαž„β€‹αž‚αžΆαŸ†αž‘αŸ’αžšβ€‹αž€αžΆαžšβ€‹αž€αŸ†αžŽαžαŸ‹β€‹αž”αŸ‰αžΆαžšαŸ‰αžΆαž˜αŸ‰αŸ‚αžαŸ’αžšβ€‹αžŠαŸ‚αž›β€‹αž„αžΆαž™β€‹αžŸαŸ’αžšαž½αž›β€‹αž”αŸ’αžšαžΎβ€‹αž αžΎαž™β€‹αžαŸ’αžšαž‘αž”αŸ‹β€‹ Cluster αžœαž·αž‰αŸ”

class Cluster {
    [ValidatePattern("^[A-z]+$")]
    [string] $Service
    [ValidateSet("TEST", "STAGE", "CANARY", "PROD")]
    [string] $FlightingRing
    [ValidateSet("EastUS", "WestUS", "NorthEurope")]
    [string] $Region
    [ValidateRange(0, 255)]
    [int] $Index
}

function New-Cluster {
    [OutputType([Cluster])]
    Param(
        [Parameter(Mandatory, ParameterSetName = "Id", Position = 0)]
        [ValidateNotNullOrEmpty()]
        [string] $Id,
        [Parameter(Mandatory, ParameterSetName = "Components")]
        [string] $Service,
        [Parameter(Mandatory, ParameterSetName = "Components")]
        [string] $FlightingRing,
        [Parameter(Mandatory, ParameterSetName = "Components")]
        [string] $Region,
        [Parameter(Mandatory, ParameterSetName = "Components")]
        [int] $Index
    )

    if ($Id) {
        $Service, $FlightingRing, $Region, $Index = $Id -split "-"
    }

    [Cluster]@{
        Service       = $Service
        FlightingRing = $FlightingRing
        Region        = $Region
        Index         = $Index
    }
}

Export-ModuleMember New-Cluster

αžαžΎαž˜αžΆαž“αž’αŸ’αžœαžΈαž‘αŸ€αžαžŠαŸ‚αž›αžαŸ’αžšαžΌαžœαž’αžΆαž“

αž’αŸ†αž–αžΈαžαŸ’αž“αžΆαž€αŸ‹
PowerShell αž€αžΆαžšαž–αžΆαžš
αž€αžΆαžšαžŸαžšαžŸαŸαžšαž€αž˜αŸ’αž˜αžœαž·αž’αžΈαž˜αž»αžαž„αžΆαžšαž“αŸ…αž€αŸ’αž“αž»αž„ PowerShell

αž”αŸ’αžšαž—αž–: www.habr.com

αž”αž“αŸ’αžαŸ‚αž˜αž˜αžαž·αž™αŸ„αž”αž›αŸ‹