рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рд╕рд╛рде рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреЙрд╡рд░рд╢реЗрд▓ рдПрдХ рд╡рд┐рд░реЛрдзрд╛рднрд╛рд╕ рдирд╣реАрдВ рд╣реИ, рдореИрдВ рдЗрд╕рдХреА рдЧрд╛рд░рдВрдЯреА рджреЗрддрд╛ рд╣реВрдВ

рдирдорд╕реНрддреЗ, рд╣рдмрд░! рдореИрдВ рдЖрдкрдХреЗ рдзреНрдпрд╛рди рдореЗрдВ рд▓реЗрдЦ рдХрд╛ рдЕрдиреБрд╡рд╛рдж рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реВрдБ "рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рд╕рд╛рде рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкрд╛рд╡рд░рд╢реЗрд▓ред
рдореИрдВ рд╡рд╛рджрд╛ рдХрд░рддрд╛ рд╣реВрдВ рдХрд┐ рдпрд╣ рд╡рд┐рд░реЛрдзрд╛рднрд╛рд╕ рдирд╣реАрдВ рд╣реИ"
рдХреНрд░рд┐рд╕реНрдЯреЛрдлрд░ рдХреБрдПрдЪ рджреНрд╡рд╛рд░рд╛ред

рдСрдмреНрдЬреЗрдХреНрдЯ-рдУрд░рд┐рдПрдВрдЯреЗрдб рдФрд░ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдкреНрд░рддрд┐рдорд╛рди рдПрдХ-рджреВрд╕рд░реЗ рдХреЗ рд╡рд┐рдкрд░реАрдд рд▓рдЧ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдкрд╛рд╡рд░рд╢реЗрд▓ рдореЗрдВ рджреЛрдиреЛрдВ рд╕рдорд╛рди рд░реВрдк рд╕реЗ рд╕рдорд░реНрдерд┐рдд рд╣реИрдВред рд▓рдЧрднрдЧ рд╕рднреА рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ, рдЪрд╛рд╣реЗ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╣реЛрдВ рдпрд╛ рдирд╣реАрдВ, рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдирд╛рдо-рдореВрд▓реНрдп рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рдХреА рд╕реБрд╡рд┐рдзрд╛рдПрдВ рд╣реЛрддреА рд╣реИрдВ; рд╕рдВрд░рдЪрдирд╛рдПрдВ рдФрд░ рд░рд┐рдХреЙрд░реНрдб рдЬреИрд╕реА рдХрдХреНрд╖рд╛рдПрдВ, рдХреЗрд╡рд▓ рдПрдХ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣реИрдВред рдпрджрд┐ рд╣рдо рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рдЕрдкрдиреЗ рдЙрдкрдпреЛрдЧ рдХреЛ рдирд╛рдореЛрдВ рдФрд░ рдореВрд▓реНрдпреЛрдВ рдХреЗ рдмрдВрдзрди рддрдХ рд╕реАрдорд┐рдд рд░рдЦрддреЗ рд╣реИрдВ, рдФрд░ рд╡рд┐рд░рд╛рд╕рдд, рдмрд╣реБрд░реВрдкрддрд╛, рдпрд╛ рдкрд░рд┐рд╡рд░реНрддрдирд╢реАрд▓рддрд╛ рдЬреИрд╕реА рднрд╛рд░реА рд╡рд╕реНрддреБ-рдЙрдиреНрдореБрдЦ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ рд╕реЗ рдмрдЪрддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдЕрдкрдиреЗ рдХреЛрдб рдХреЛ рдЬрдЯрд┐рд▓ рдХрд┐рдП рдмрд┐рдирд╛ рдЙрдирдХрд╛ рд▓рд╛рдн рдЙрдард╛ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЕрдкрд░рд┐рд╡рд░реНрддрдиреАрдп рдкреНрд░рдХрд╛рд░ рдХреЗ рд░реВрдкрд╛рдВрддрд░рдг рддрд░реАрдХреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдХрд░, рд╣рдо рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рд╕рд╛рде рдЕрдкрдиреЗ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдХреЛрдб рдХреЛ рд╕рдореГрджреНрдз рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдЬрд╛рддрд┐рдпреЛрдВ рдХрд╛ рдЬрд╛рджреВ

рдкреЙрд╡рд░рд╢реЗрд▓ рдореЗрдВ рдЬрд╛рддрд┐рдпрд╛рдБ рд╕рдмрд╕реЗ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИрдВред рдЬрдм рдЖрдк рдХреЛрдИ рдорд╛рди рдбрд╛рд▓рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдкрд░реНрдпрд╛рд╡рд░рдг рджреНрд╡рд╛рд░рд╛ рдЖрдкрдХреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдЬреЛрдбрд╝реЗ рдЧрдП рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдЖрд░рдВрднреАрдХрд░рдг рдФрд░ рд╕рддреНрдпрд╛рдкрди рдХреНрд╖рдорддрд╛рдУрдВ рдкрд░ рднрд░реЛрд╕рд╛ рдХрд░ рд░рд╣реЗ рд╣реЛрддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдмрд╕ [xml] рдореЗрдВ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдбрд╛рд▓рдиреЗ рд╕реЗ рдпрд╣ рдкрд╛рд░реНрд╕рд░ рдХреЛрдб рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЪрд▓реЗрдЧрд╛ рдФрд░ рдПрдХ рдкреВрд░реНрдг xml рдЯреНрд░реА рдЙрддреНрдкрдиреНрди рд╣реЛрдЧрд╛ред рд╣рдо рдЙрд╕реА рдЙрджреНрджреЗрд╢реНрдп рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рдХреЛрдб рдореЗрдВ рдХреНрд▓рд╛рд╕реЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рд╣реИрд╢рдЯреЗрдмрд▓ рдХрд╛рд╕реНрдЯ рдХрд░реЗрдВ

рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдХреЛрдИ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдирд╣реАрдВ рд╣реИ, рддреЛ рдЖрдк рдЕрдкрдиреЗ рдХреНрд▓рд╛рд╕ рдкреНрд░рдХрд╛рд░ рдореЗрдВ рд╣реИрд╢рдЯреЗрдмрд▓ рдХрд╛рд╕реНрдЯ рдХрд░рдХреЗ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЗ рдмрд┐рдирд╛ рднреА рдЬрд╛рд░реА рд░рдЦ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕ рдкреИрдЯрд░реНрди рдХрд╛ рдкреВрд░рд╛ рд▓рд╛рдн рдЙрдард╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рддреНрдпрд╛рдкрди рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рди рднреВрд▓реЗрдВред рд╕рд╛рде рд╣реА, рд╣рдо рдХрдХреНрд╖рд╛ рдХреЗ рдЯрд╛рдЗрдк рдХрд┐рдП рдЧрдП рдЧреБрдгреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдФрд░ рднреА рдЧрд╣рди рдЖрд░рдВрднреАрдХрд░рдг рдФрд░ рд╕рддреНрдпрд╛рдкрди рддрд░реНрдХ рдХреЛ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

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
}

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдХрд╛рд╕реНрдЯрд┐рдВрдЧ рд╕реЗ рд╕реНрд╡рдЪреНрдЫ рдЖрдЙрдЯрдкреБрдЯ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдорд┐рд▓рддреА рд╣реИред рдпрджрд┐ рдЖрдк рдкрд╣рд▓реА рдмрд╛рд░ рдЗрди рд╣реИрд╢рдЯреЗрдмрд▓реНрд╕ рдХреЛ рдПрдХ рдХреНрд▓рд╛рд╕ рдореЗрдВ рдбрд╛рд▓рддреЗ рд╣реИрдВ, рддреЛ рдлрд╝реЙрд░реНрдореЗрдЯ-рдЯреЗрдмрд▓ рдореЗрдВ рдкрд╛рд╕ рдХрд┐рдП рдЧрдП рдХреНрд▓рд╕реНрдЯрд░ рд╣реИрд╢рдЯреЗрдмрд▓ рдРрд░реЗ рдХреЗ рдЖрдЙрдЯрдкреБрдЯ рдХреА рддреБрд▓рдирд╛ рдХрд░реЗрдВред рдХрд┐рд╕реА рд╡рд░реНрдЧ рдХреЗ рдЧреБрдгреЛрдВ рдХреЛ рд╣рдореЗрд╢рд╛ рдЙрд╕реА рдХреНрд░рдо рдореЗрдВ рд╕реВрдЪреАрдмрджреНрдз рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕ рдХреНрд░рдо рдореЗрдВ рдЙрдиреНрд╣реЗрдВ рд╡рд╣рд╛рдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЙрди рд╕рднреА рдЧреБрдгреЛрдВ рд╕реЗ рдкрд╣рд▓реЗ рдЫрд┐рдкреЗ рд╣реБрдП рдХреАрд╡рд░реНрдб рдХреЛ рдЬреЛрдбрд╝рдирд╛ рди рднреВрд▓реЗрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдЖрдк рдкрд░рд┐рдгрд╛рдореЛрдВ рдореЗрдВ рджрд┐рдЦрд╛рдИ рдирд╣реАрдВ рджреЗрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред

рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рд╕рд╛рде рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреЙрд╡рд░рд╢реЗрд▓ рдПрдХ рд╡рд┐рд░реЛрдзрд╛рднрд╛рд╕ рдирд╣реАрдВ рд╣реИ, рдореИрдВ рдЗрд╕рдХреА рдЧрд╛рд░рдВрдЯреА рджреЗрддрд╛ рд╣реВрдВ

рдЕрд░реНрдереЛрдВ рдХреА рдЬрд╛рддрд┐

рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рддрд░реНрдХ рдХреЗ рд╕рд╛рде рдПрдХ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рд╣реИ, рддреЛ рдЖрдкрдХреЗ рдХреНрд▓рд╛рд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдорд╛рди рдбрд╛рд▓рдиреЗ рд╕реЗ рдЖрдкрдХреЗ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЛ рдорд╛рди рдкрд╛рд╕ рд╣реЛ рдЬрд╛рдПрдЧрд╛, рдЬрд╣рд╛рдВ рдЖрдк рдЕрдкрдиреА рдХреНрд▓рд╛рд╕ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдкреНрд░рд╛рд░рдВрдн рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ

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"

рд▓рд╛рдЗрди рдореЗрдВ рдбрд╛рд▓рдирд╛

рдЖрдк рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХреЗ рдкреАрдЫреЗ рддрд░реНрдХ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП [рд╕реНрдЯреНрд░рд┐рдВрдЧ] 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'"

рдХреНрд░рдордмрджреНрдз рдЙрджрд╛рд╣рд░рдг рдХрд╛рд╕реНрдЯ рдХрд░реЗрдВ

рдХрд╛рд╕реНрдЯ рд╕реБрд░рдХреНрд╖рд┐рдд рдЕрдХреНрд░рдорд╛рдВрдХрди рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдпрджрд┐ рдбреЗрдЯрд╛ рдХреНрд▓рд╕реНрдЯрд░ рдореЗрдВ рд╣рдорд╛рд░реЗ рд╡рд┐рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЛ рдкреВрд░рд╛ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рддреЛ рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдЙрджрд╛рд╣рд░рдг рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рдПрдВрдЧреЗ

# ╨Т╨░╨╗╨╕╨┤╨░╤Ж╨╕╤П ╤Б╨╡╤А╨╕╨░╨╗╨╕╨╖╨╛╨▓╨░╨╜╨╜╤Л╤Е ╨┤╨░╨╜╨╜╤Л╤Е

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

рдЖрдкрдХреЗ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдХреЛрдб рдореЗрдВ рдЬрд╛рддрд┐рдпрд╛рдБ

рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдкрд╣рд▓реЗ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдлрд┐рд░ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛ рдЕрдкрд░рд┐рд╡рд░реНрддрдиреАрдп рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдкрд░ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЗ рдЕрдиреБрдХреНрд░рдо рдХреЗ рд░реВрдк рдореЗрдВ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВред рд╡рд┐рд░реЛрдзрд╛рднрд╛рд╕реА рдзрд╛рд░рдгрд╛ рдХреЗ рдмрд╛рд╡рдЬреВрдж, рдкреНрд░рдХрд╛рд░ рд░реВрдкрд╛рдВрддрд░рдг рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рдХрд╛рд░рдг рдХрдХреНрд╖рд╛рдПрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЖрдкрдХреЛ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдХреЛрдб рд▓рд┐рдЦрдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддреА рд╣реИрдВред

рдХреНрдпрд╛ рдореИрдВ рдЬреЛ рдкрд╛рд╡рд░рд╢реЗрд▓ рд▓рд┐рдЦ рд░рд╣рд╛ рд╣реВрдВ рд╡рд╣ рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рд╣реИ?

C# рдпрд╛ рд╕рдорд╛рди рдкреГрд╖реНрдарднреВрдорд┐ рд╕реЗ рдЖрдиреЗ рд╡рд╛рд▓реЗ рдмрд╣реБрдд рд╕реЗ рд▓реЛрдЧ Powershell рд▓рд┐рдЦ рд░рд╣реЗ рд╣реИрдВ, рдЬреЛ C# рдХреЗ рд╕рдорд╛рди рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рд╕реЗ, рдЖрдк рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рджреВрд░ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВ рдФрд░ рд╕рдВрднрд╡рддрдГ рдкрд╛рд╡рд░рд╢реЗрд▓ рдореЗрдВ рдСрдмреНрдЬреЗрдХреНрдЯ-рдУрд░рд┐рдПрдВрдЯреЗрдб рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдореЗрдВ рдЧрд╣рд░рд╛рдИ рд╕реЗ рдЧреЛрддрд╛ рд▓рдЧрд╛рдиреЗ рдпрд╛ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рд╕реАрдЦрдиреЗ рд╕реЗ рд▓рд╛рдн рд╣реЛрдЧрд╛ред

рдпрджрд┐ рдЖрдк рдкрд╛рдЗрдкрд▓рд╛рдЗрдиреЛрдВ (|), рд╡реНрд╣реЗрдпрд░-рдСрдмреНрдЬреЗрдХреНрдЯ, рдлреЙрд░рдПрдЪ-рдСрдмреНрдЬреЗрдХреНрдЯ, рд╕реЗрд▓реЗрдХреНрдЯ-рдСрдмреНрдЬреЗрдХреНрдЯ, рдЧреНрд░реБрдк-рдСрдмреНрдЬреЗрдХреНрдЯ, рд╕реЙрд░реНрдЯ-рдСрдмреНрдЬреЗрдХреНрдЯ рдЗрддреНрдпрд╛рджрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдкрд░рд┐рд╡рд░реНрддрдиреАрдп рдбреЗрдЯрд╛ рдХреЛ рдмрджрд▓рдиреЗ рдкрд░ рдмрд╣реБрдд рдЕрдзрд┐рдХ рднрд░реЛрд╕рд╛ рдХрд░рддреЗ рд╣реИрдВ - рддреЛ рдЖрдкрдХреЗ рдкрд╛рд╕ рдЕрдзрд┐рдХ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╢реИрд▓реА рд╣реИ рдФрд░ рдЖрдкрдХреЛ рдкрд╛рд╡рд░рд╢реЗрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рд▓рд╛рдн рд╣реЛрдЧрд╛ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╢реИрд▓реА рдореЗрдВ рдХрдХреНрд╖рд╛рдПрдВред

рдХрдХреНрд╖рд╛рдУрдВ рдХрд╛ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдЙрдкрдпреЛрдЧ

рдЬрд╛рддрд┐рдпрд╛рдБ, рд╣рд╛рд▓рд╛рдБрдХрд┐ рд╡реЗ рдПрдХ рд╡реИрдХрд▓реНрдкрд┐рдХ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреА рд╣реИрдВ, рдХреЗрд╡рд▓ рджреЛ рдбреЛрдореЗрди рдХреЗ рдмреАрдЪ рдПрдХ рдорд╛рдирдЪрд┐рддреНрд░рдг рд╣реИрдВред рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдореЗрдВ, рдЖрдк ForEach-Object рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдорд╛рдиреЛрдВ рдХреА рдПрдХ рд╕рд░рдгреА рдХреЛ рдореИрдк рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд╣рд░ рдмрд╛рд░ рдбреЗрдЯрд╛рдо рдХрд╛рд╕реНрдЯ рдХрд░рдиреЗ рдкрд░ рдиреЛрдб рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдЗрд╕рд╕реЗ рд╣рдореЗрдВ рдЙрдЪрд┐рдд рдорд╛рддреНрд░рд╛ рдореЗрдВ рдХреЛрдб рд▓рд┐рдЦрдиреЗ рд╕реЗ рдмрдЪрдиреЗ рдХрд╛ рдореМрдХрд╛ рдорд┐рд▓рддрд╛ рд╣реИред рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рд╣рдорд╛рд░реА рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдШреЛрд╖рдгрд╛рддреНрдордХ рдбреЗрдЯрд╛ рдХреНрд╡реЗрд░реА рдФрд░ рдПрдХрддреНрд░реАрдХрд░рдг рдкрд░ рдХреЗрдВрджреНрд░рд┐рдд рд╣реИ, рдЬрдмрдХрд┐ рд╣рдорд╛рд░реА рдХрдХреНрд╖рд╛рдПрдВ рдбреЗрдЯрд╛ рдкрд╛рд░реНрд╕рд┐рдВрдЧ рдФрд░ рд╕рддреНрдпрд╛рдкрди рдХрд╛ рдзреНрдпрд╛рди рд░рдЦрддреА рд╣реИрдВред

# ╨Я╤А╨╕╨╝╨╡╤А ╨║╨╛╨╝╨▒╨╕╨╜╨╕╤А╨╛╨▓╨░╨╜╨╕╤П ╨║╨╗╨░╤Б╤Б╨╛╨▓ ╤Б ╨║╨╛╨╜╨▓╨╡╨╣╨╡╤А╨░╨╝╨╕ ╨┤╨╗╤П 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 рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рд╣реИрдВ

  • рдЖрдк рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдлрд╝рд╛рдЗрд▓ рдХреЛ рдбреЙрдЯрд╕реЛрд░реНрд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:ред ./my-classes.ps1. рдпрд╣ рдЖрдкрдХреЗ рд╡рд░реНрддрдорд╛рди рджрд╛рдпрд░реЗ рдореЗрдВ my-classes.ps1 рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдЧрд╛ рдФрд░ рд╡рд╣рд╛рдВ рдлрд╝рд╛рдЗрд▓ рд╕реЗ рд╕рднреА рдХрдХреНрд╖рд╛рдУрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдЧрд╛ред

  • рдЖрдк рдПрдХ рдкреЙрд╡рд░рд╢реЗрд▓ рдореЙрдбреНрдпреВрд▓ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдЖрдкрдХреЗ рд╕рднреА рдХрд╕реНрдЯрдо рдПрдкреАрдЖрдИ (cmdlet) рдХреЛ рдирд┐рд░реНрдпрд╛рдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЖрдкрдХреЗ рдореЙрдбреНрдпреВрд▓ рдореЗрдирд┐рдлреЗрд╕реНрдЯ рдореЗрдВ ScriptsToProcess = "./my-classes.ps1" рд╡реЗрд░рд┐рдПрдмрд▓ рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИ, рдЙрд╕реА рдкрд░рд┐рдгрд╛рдо рдХреЗ рд╕рд╛рде: ./my-classes.ps1 рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛрдЧрд╛ рдЖрдкрдХрд╛ рд╡рд╛рддрд╛рд╡рд░рдг.

рдЖрдк рдЬреЛ рднреА рд╡рд┐рдХрд▓реНрдк рдЪреБрдиреЗрдВ, рдзреНрдпрд╛рди рд░рдЦреЗрдВ рдХрд┐ рдкрд╛рд╡рд░рд╢реЗрд▓ рдХрд╛ рдкреНрд░рдХрд╛рд░ рд╕рд┐рд╕реНрдЯрдо рд╡рд┐рднрд┐рдиреНрди рд╕реНрдерд╛рдиреЛрдВ рд╕реЗ рд▓реЛрдб рдХрд┐рдП рдЧрдП рд╕рдорд╛рди рдирд╛рдо рдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рд╣рд▓ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИред
рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЕрдЧрд░ рдЖрдкрдиреЗ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╕реНрдерд╛рдиреЛрдВ рд╕реЗ рд╕рдорд╛рди рдЧреБрдгреЛрдВ рд╡рд╛рд▓реА рджреЛ рд╕рдорд╛рди рдХрдХреНрд╖рд╛рдПрдВ рд▓реЛрдб рдХреА рд╣реИрдВ, рддреЛ рднреА рдЖрдк рд╕рдорд╕реНрдпрд╛рдУрдВ рдореЗрдВ рдкрдбрд╝рдиреЗ рдХрд╛ рдЬреЛрдЦрд┐рдо рдЙрдард╛рддреЗ рд╣реИрдВред

рдЖрдЧреЗ рдХрд╛ рд░рд╛рд╕реНрддрд╛

рдкреНрд░рдХрд╛рд░ рд╕рдорд╛рдзрд╛рди рд╕рдорд╕реНрдпрд╛рдУрдВ рд╕реЗ рдмрдЪрдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдЕрдкрдиреА рдХрдХреНрд╖рд╛рдУрдВ рдХреЛ рдХрднреА рднреА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рд╕рд╛рдордиреЗ рдЙрдЬрд╛рдЧрд░ рди рдХрд░реЗрдВред рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реЗ рд╡рд░реНрдЧ-рдкрд░рд┐рднрд╛рд╖рд┐рдд рдкреНрд░рдХрд╛рд░ рдХреЛ рдЖрдпрд╛рдд рдХрд░рдиреЗ рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рдЕрдкрдиреЗ рдореЙрдбреНрдпреВрд▓ рд╕реЗ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдирд┐рд░реНрдпрд╛рдд рдХрд░реЗрдВ рдЬреЛ рд╕реАрдзреЗ рд╡рд░реНрдЧ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░ рджреЗрддрд╛ рд╣реИред рдХреНрд▓рд╕реНрдЯрд░ рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рдиреНрдпреВ-рдХреНрд▓рд╕реНрдЯрд░ рдлрд╝рдВрдХреНрд╢рди рдирд┐рд░реНрдпрд╛рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдЕрдиреБрдХреВрд▓ рдкреИрд░рд╛рдореАрдЯрд░ рд╕реЗрдЯ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░реЗрдЧрд╛ рдФрд░ рдПрдХ рдХреНрд▓рд╕реНрдЯрд░ рд▓реМрдЯрд╛рдПрдЧрд╛ред

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

рдФрд░ рдХреНрдпрд╛ рдкрдврд╝реЗрдВ

рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ
рд░рдХреНрд╖рд╛рддреНрдордХ рдкрд╛рд╡рд░рд╢реЗрд▓
рдкреЙрд╡рд░рд╢реЗрд▓ рдореЗрдВ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ

рд╕реНрд░реЛрдд: www.habr.com

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдЬреЛрдбрд╝реЗрдВ