рдХрдХреНрд╖рд╛рд╣рд░реВрд╕рдБрдЧ рдХрд╛рд░реНрдпрд╛рддреНрдордХ Powershell рдПрдХ рдЕрдХреНрд╕рд┐рдореЛрд░рди рд╣реЛрдЗрди, рдо рдпрд╕рдХреЛ рдЧреНрдпрд╛рд░реЗрдиреНрдЯреА рджрд┐рдиреНрдЫреБ

рд╣реЗ рд╣рд╛рдмрд░! рдо рддрдкрд╛рдИрдВрдХреЛ рдзреНрдпрд╛рдирд╛рдХрд░реНрд╖рдгрдорд╛ рд▓реЗрдЦрдХреЛ рдЕрдиреБрд╡рд╛рдж рдкреНрд░рд╕реНрддреБрдд рдЧрд░реНрджрдЫреБ "рд╡рд░реНрдЧрд╣рд░реВрд╕рдБрдЧ рдХрд╛рд░реНрдпрд╛рддреНрдордХ PowerShellред
рдо рд╡рдЪрди рджрд┐рдиреНрдЫреБ рдХрд┐ рдпреЛ рдЕрдХреНрд╕рд┐рдореЛрд░рди рд╣реЛрдЗрди"
рдХреНрд░рд┐рд╕реНрдЯреЛрдлрд░ рдХреБрдЪ рджреНрд╡рд╛рд░рд╛ред

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

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

рдЬрд╛рддрд╣рд░реВ Powershell рдорд╛ рд╕рдмреИрднрдиреНрджрд╛ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рд╡рд┐рд╢реЗрд╖рддрд╛рд╣рд░реВ рдордзреНрдпреЗ рдПрдХ рд╣реЛред рдЬрдм рддрдкрд╛рдЗрдБ рдорд╛рди рдХрд╛рд╕реНрдЯ рдЧрд░реНрдиреБрд╣реБрдиреНрдЫ, рддрдкрд╛рдЗрдБ рдирд┐рд╣рд┐рдд рдкреНрд░рд╛рд░рдореНрднрд┐рдХрддрд╛ рд░ рдкреНрд░рдорд╛рдгреАрдХрд░рдг рдХреНрд╖рдорддрд╛рд╣рд░реВрдорд╛ рднрд░ рдкрд░реНрджреИ рд╣реБрдиреБрд╣реБрдиреНрдЫ рд╡рд╛рддрд╛рд╡рд░рдгрд▓реЗ рддрдкрд╛рдЗрдБрдХреЛ рдЕрдиреБрдкреНрд░рдпреЛрдЧрдорд╛ рдердкреНрдЫред рдЙрджрд╛рд╣рд░рдг рдХреЛ рд▓рд╛рдЧреА, рдХреЗрд╡рд▓ [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
}

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

рдХрдХреНрд╖рд╛рд╣рд░реВрд╕рдБрдЧ рдХрд╛рд░реНрдпрд╛рддреНрдордХ Powershell рдПрдХ рдЕрдХреНрд╕рд┐рдореЛрд░рди рд╣реЛрдЗрди, рдо рдпрд╕рдХреЛ рдЧреНрдпрд╛рд░реЗрдиреНрдЯреА рджрд┐рдиреНрдЫреБ

рдЕрд░реНрдерд╣рд░реВрдХреЛ рдХрд╛рд╕реНрдЯ

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

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 рд╕реБрд░рдХреНрд╖рд┐рдд deserialization рдЕрдиреБрдорддрд┐ рджрд┐рдиреНрдЫред рдпрджрд┐ рдбреЗрдЯрд╛рд▓реЗ рдХреНрд▓рд╕реНрдЯрд░рдорд╛ рд╣рд╛рдореНрд░реЛ рд╡рд┐рд╢рд┐рд╖реНрдЯрддрд╛ рдкреВрд░рд╛ рдЧрд░реНрджреИрди рднрдиреЗ рддрд▓рдХрд╛ рдЙрджрд╛рд╣рд░рдгрд╣рд░реВ рдЕрд╕рдлрд▓ рд╣реБрдиреЗрдЫрдиреН

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

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

рддрдкрд╛рдИрдВрдХреЛ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдХреЛрдбрдорд╛ рдЬрд╛рддрд╣рд░реВ

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

рдХреЗ рдореИрд▓реЗ рд▓реЗрдЦрд┐рд░рд╣реЗрдХреЛ Powershell рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдЫ?

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

рдпрджрд┐ рддрдкрд╛рдИрдВ рдкрд╛рдЗрдкрд▓рд╛рдЗрдирд╣рд░реВ (|), Where-Object, ForEach-Object, Select-Object, Group-Object, Sort-Object, рдЖрджрд┐ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдЕрдкрд░рд┐рд╡рд░реНрддрдиреАрдп рдбреЗрдЯрд╛ рд░реВрдкрд╛рдиреНрддрд░рдгрдорд╛ рдзреЗрд░реИ рдирд┐рд░реНрднрд░ рд╣реБрдиреБрд╣реБрдиреНрдЫ рднрдиреЗ - рддрдкрд╛рдИрдВрд╕рдБрдЧ рдердк рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╢реИрд▓реА рдЫ рд░ рддрдкрд╛рдИрдВрд▓реЗ Powershell рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рд▓рд╛рдн рдЙрдард╛рдЙрдиреБрд╣реБрдиреЗрдЫред рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╢реИрд▓реАрдорд╛ рдХрдХреНрд╖рд╛рд╣рд░реВред

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

рдЬрд╛рддрд┐рд╣рд░реВ, рдпрджреНрдпрдкрд┐ рддрд┐рдиреАрд╣рд░реВрд▓реЗ рд╡реИрдХрд▓реНрдкрд┐рдХ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдЫрдиреН, рджреБрдИ рдбреЛрдореЗрдирд╣рд░реВ рдмреАрдЪрдХреЛ рдореНрдпрд╛рдкрд┐рдЩ рдорд╛рддреНрд░ рд╣реБрдиреНред рдкрд╛рдЗрдкрд▓рд╛рдЗрдирдорд╛, рддрдкрд╛рдИрдВрд▓реЗ 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 рд▓рд╛рдИ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЧрд░реНрдиреЗрдЫ рд░ рддреНрдпрд╣рд╛рдБ рдлрд╛рдЗрд▓рдмрд╛рдЯ рд╕рдмреИ рдХрдХреНрд╖рд╛рд╣рд░реВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдЧрд░реНрдиреЗрдЫред

  • рддрдкрд╛рдИрдВ рдПрдХ Powershell рдореЛрдбреНрдпреБрд▓ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ рдЬрд╕рд▓реЗ рддрдкрд╛рдИрдВрдХреЛ рд╕рдмреИ рдЕрдиреБрдХреВрд▓рди API (cmdlets) рдирд┐рд░реНрдпрд╛рдд рдЧрд░реНрджрдЫ рд░ рддрдкрд╛рдИрдВрдХреЛ рдореЛрдбреНрдпреБрд▓ manifest рдорд╛ ScriptsToProcess = "./my-classes.ps1" рднреЗрд░рд┐рдПрдмрд▓ рд╕реЗрдЯ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ, рд╕рдорд╛рди рдкрд░рд┐рдгрд╛рдордХреЛ рд╕рд╛рде: ./my-classes.ps1 рдорд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реБрдиреЗрдЫред рдЖрдлреНрдиреЛ рд╡рд╛рддрд╛рд╡рд░рдгред

рддрдкрд╛рдИрдВрд▓реЗ рдЬреБрдирд╕реБрдХреИ рд╡рд┐рдХрд▓реНрдк рд░реЛрдЬреНрдиреБрд╣реБрдиреНрдЫ, рдзреНрдпрд╛рди рд░рд╛рдЦреНрдиреБрд╣реЛрд╕реН рдХрд┐ Powershell рдХреЛ рдкреНрд░рдХрд╛рд░ рдкреНрд░рдгрд╛рд▓реАрд▓реЗ рдлрд░рдХ рдард╛рдЙрдБрд╣рд░реВрдмрд╛рдЯ рд▓реЛрдб рдЧрд░рд┐рдПрдХрд╛ рдПрдЙрдЯреИ рдирд╛рдордХрд╛ рдкреНрд░рдХрд╛рд░рд╣рд░реВ рд╕рдорд╛рдзрд╛рди рдЧрд░реНрди рд╕рдХреНрджреИрдиред
рдпрджрд┐ рддрдкрд╛рдИрдВрд▓реЗ рдлрд░рдХ рдард╛рдЙрдБрдмрд╛рдЯ рдПрдЙрдЯреИ рдЧреБрдгрд╣рд░реВ рднрдПрдХрд╛ рджреБрдИрд╡рдЯрд╛ рд╕рдорд╛рди рд╡рд░реНрдЧрд╣рд░реВ рд▓реЛрдб рдЧрд░реНрдиреБрднрдпреЛ рднрдиреЗ рдкрдирд┐, рддрдкрд╛рдИрдВ рд╕рдорд╕реНрдпрд╛рдорд╛ рдкрд░реНрдиреЗ рдЬреЛрдЦрд┐рдордорд╛ рд╣реБрдиреБрд╣реБрдиреНрдЫред

рдЕрдЧрд╛рдбрд┐ рдмрд╛рдЯреЛ

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

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

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдердкреНрди