ΠΠ΄ΡΠ°Π²Π΅ΠΉ, Π₯Π°Π±ΡΡ! ΠΡΠ΅Π΄ΡΡΠ°Π²ΡΠΌ Π²ΠΈ ΠΏΡΠ΅Π²ΠΎΠ΄ Π½Π° ΡΡΠ°ΡΠΈΡ Π°Π²ΡΠΎΡΡΡ Π΅ Christopher Kuech.
ΠΠ±Π΅ΠΊΡΠ½ΠΎ-ΠΎΡΠΈΠ΅Π½ΡΠΈΡΠ°Π½Π°ΡΠ° ΠΈ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»Π½Π°ΡΠ° ΠΏΠ°ΡΠ°Π΄ΠΈΠ³ΠΌΠΈ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ°Π½Π΅ΡΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π°Ρ Π½Π΅ΡΡΠ²ΠΌΠ΅ΡΡΠΈΠΌΠΈ, Π½ΠΎ ΠΈ Π΄Π²Π΅ΡΠ΅ ΡΠ° ΡΠ°Π²Π½ΠΎΠΏΠΎΡΡΠ°Π²Π΅Π½ΠΈ Π² PowerShell. ΠΠΎΡΡΠΈ Π²ΡΠΈΡΠΊΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ°ΡΠΈ Π΅Π·ΠΈΡΠΈ, ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»Π½ΠΈ ΠΈΠ»ΠΈ Π½Π΅, ΡΠ°Π·ΠΏΠΎΠ»Π°Π³Π°Ρ Ρ ΡΡΠ΅Π΄ΡΡΠ²Π° Π·Π° ΡΠ°Π·ΡΠΈΡΠ΅Π½ΠΎ ΡΠ²ΡΡΠ·Π²Π°Π½Π΅ Π½Π° ΠΈΠΌΠ΅Π½Π° ΠΈ ΡΡΠΎΠΉΠ½ΠΎΡΡΠΈ; ΠΠ»Π°ΡΠΎΠ²Π΅ΡΠ΅, ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎ Π½Π° struct-ΠΎΠ²Π΅ ΠΈ record-ΠΎΠ²Π΅, ΡΠ° ΡΠ°ΠΌΠΎ Π΅Π΄ΠΈΠ½ ΠΎΡ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΠΈΡΠ΅. ΠΠΊΠΎ ΠΎΠ³ΡΠ°Π½ΠΈΡΠΈΠΌ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ΡΠΎ Π½Π° ΠΊΠ»Π°ΡΠΎΠ²Π΅ΡΠ΅ Π΄ΠΎ ΡΠ²ΡΡΠ·Π²Π°Π½Π΅ΡΠΎ Π½Π° ΠΈΠΌΠ΅Π½Π° ΠΈ ΡΡΠΎΠΉΠ½ΠΎΡΡΠΈ ΠΈ ΠΈΠ·Π±Π΅Π³Π½Π΅ΠΌ "ΡΠ΅ΠΆΠΊΠΈΡΠ΅" ΠΎΠ±Π΅ΠΊΡΠ½ΠΎ-ΠΎΡΠΈΠ΅Π½ΡΠΈΡΠ°Π½ΠΈ ΠΊΠΎΠ½ΡΠ΅ΠΏΡΠΈΠΈ, ΠΊΠ°ΡΠΎ Π½Π°ΡΠ»Π΅Π΄ΡΠ²Π°Π½Π΅, ΠΏΠΎΠ»ΠΈΠΌΠΎΡΡΠΈΠ·ΡΠΌ ΠΈΠ»ΠΈ ΠΈΠ·ΠΌΠ΅Π½ΡΠ΅ΠΌΠΎΡΡ, ΡΠ΅ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° ΡΠ΅ Π²ΡΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΠΎΡ ΡΠ΅Ρ Π½ΠΈΡΠ΅ ΠΏΡΠ΅Π΄ΠΈΠΌΡΡΠ²Π°, Π±Π΅Π· Π΄Π° ΡΡΠ»ΠΎΠΆΠ½ΡΠ²Π°ΠΌΠ΅ ΠΊΠΎΠ΄Π° ΡΠΈ. ΠΡΠ²Π΅Π½ ΡΠΎΠ²Π°, Π΄ΠΎΠ±Π°Π²ΡΠΉΠΊΠΈ Π½Π΅ΠΈΠ·ΠΌΠ΅Π½ΡΠ΅ΠΌΠΈ ΠΌΠ΅ΡΠΎΠ΄ΠΈ Π·Π° ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΡΠ²Π°Π½Π΅ Π½Π° ΡΠΈΠΏΠΎΠ²Π΅, ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° ΠΎΠ±ΠΎΠ³Π°ΡΠΈΠΌ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»Π½ΠΈΡ ΡΠΈ ΠΊΠΎΠ΄ Ρ ΠΊΠ»Π°ΡΠΎΠ²Π΅.
ΠΠ°Π³ΠΈΡΡΠ° Π½Π° ΠΊΠ°ΡΡΠΎΠ²Π΅ΡΠ΅
ΠΠ°ΡΡΠΎΠ²Π΅ΡΠ΅ ΡΠ° Π΅Π΄Π½ΠΎ ΠΎΡ Π½Π°ΠΉ-ΠΌΠΎΡΠ½ΠΈΡΠ΅ ΠΏΡΠ΅Π΄ΠΈΠΌΡΡΠ²Π° Π² 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
}ΠΡΠ²Π΅Π½ ΡΠΎΠ²Π°, ΠΊΠ°ΡΡΡΡ ΠΏΠΎΠΌΠ°Π³Π° Π·Π° ΠΏΠΎΠ»ΡΡΠ°Π²Π°Π½Π΅ Π½Π° ΡΠΈΡΡ ΠΈΠ·Ρ ΠΎΠ΄. Π‘ΡΠ°Π²Π½Π΅ΡΠ΅ ΠΈΠ·Ρ ΠΎΠ΄Π° Π½Π° ΠΌΠ°ΡΠΈΠ²Π° ΠΎΡ Ρ Π΅ΡΡΠ°Π±Π»ΠΈΡΠΈ Cluster, ΠΏΡΠ΅Π΄Π°Π΄Π΅Π½ Π½Π° Format-Table, Ρ ΡΠΎΠ²Π°, ΠΊΠΎΠ΅ΡΠΎ ΡΠ΅ ΠΏΠΎΠ»ΡΡΠΈΡΠ΅, Π°ΠΊΠΎ ΠΏΡΠ΅Π΄ΠΈ ΡΠΎΠ²Π° ΠΊΠ°ΡΡΠ²Π°ΡΠ΅ ΡΠ΅Π·ΠΈ Ρ Π΅ΡΡΠ°Π±Π»ΠΈΡΠΈ Π² ΠΊΠ»Π°Ρ. Π‘Π²ΠΎΠΉΡΡΠ²Π°ΡΠ° Π½Π° ΠΊΠ»Π°ΡΠ° Π²ΠΈΠ½Π°Π³ΠΈ ΡΠ΅ ΠΈΠ·Π±ΡΠΎΡΠ²Π°Ρ Π² ΡΠ΅Π΄Π°, Π² ΠΊΠΎΠΉΡΠΎ ΡΠ° ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈ. ΠΠ΅ Π·Π°Π±ΡΠ°Π²ΡΠΉΡΠ΅ Π΄Π° Π΄ΠΎΠ±Π°Π²ΠΈΡΠ΅ ΠΊΠ»ΡΡΠΎΠ²Π°ΡΠ° Π΄ΡΠΌΠ° hidden ΠΏΡΠ΅Π΄ Π²ΡΠΈΡΠΊΠΈ ΡΠ΅Π·ΠΈ ΡΠ²ΠΎΠΉΡΡΠ²Π°, ΠΊΠΎΠΈΡΠΎ Π½Π΅ ΡΡΡΠ±Π²Π° Π΄Π° ΡΠ΅ Π²ΠΈΠΆΠ΄Π°Ρ Π² ΠΈΠ·Ρ ΠΎΠ΄Π°.

ΠΠ°ΡΡ Π½Π° ΡΡΠΎΠΉΠ½ΠΎΡΡΠΈ
ΠΠΊΠΎ ΠΈΠΌΠ°ΡΠ΅ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ Ρ Π΅Π΄ΠΈΠ½ Π°ΡΠ³ΡΠΌΠ΅Π½Ρ, ΠΊΠ°ΡΡΠ²Π°Π½Π΅ΡΠΎ Π½Π° ΡΡΠΎΠΉΠ½ΠΎΡΡΡΠ° ΠΊΡΠΌ Π²Π°ΡΠΈΡ ΠΊΠ»Π°Ρ ΡΠ΅ ΠΏΡΠ΅Π΄Π°Π΄Π΅ ΡΡΠΎΠΉΠ½ΠΎΡΡΡΠ° Π½Π° ΡΠΎΠ·ΠΈ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ, Π² ΠΊΠΎΠΉΡΠΎ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠ°ΡΠ΅ ΠΈΠ½ΡΡΠ°Π½ΡΠΈΡ Π½Π° Π²Π°ΡΠΈΡ ΠΊΠ»Π°Ρ
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 "Π’ΠΎΠΊΡ-ΡΠΎ ΡΡΠ·Π΄Π°Π΄ΠΎΡ
ΠΌΠ΅ ΠΌΠΎΠ΄Π΅Π» Π·Π° '$cluster'"ΠΠ°ΡΡ Π½Π° ΡΠ΅ΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠ°Π½ΠΈ ΠΈΠ½ΡΡΠ°Π½ΡΠΈΠΈ
ΠΠ°ΡΡΡΡ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ²Π° Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½Π° Π΄Π΅ΡΠ΅ΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ. ΠΡΠΈΠΌΠ΅ΡΠΈ ΠΏΠΎ-Π΄ΠΎΠ»Ρ ΡΠ΅ Π·Π°Π²ΡΡΡΠ°Ρ Ρ Π³ΡΠ΅ΡΠΊΠ°, Π°ΠΊΠΎ Π΄Π°Π½Π½ΠΈΡΠ΅ Π½Π΅ ΠΎΡΠ³ΠΎΠ²Π°ΡΡΡ Π½Π° Π½Π°ΡΠ°ΡΠ° ΡΠΏΠ΅ΡΠΈΡΠΈΠΊΠ°ΡΠΈΡ Π² Cluster
# ΠΠ°Π»ΠΈΠ΄Π°ΡΠΈΡ ΡΠ΅ΡΠΈΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½ΡΡ
Π΄Π°Π½Π½ΡΡ
[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.
Π ΠΏΡΠΈΠΌΠ΅ΡΠ° ΠΏΠΎ-Π΄ΠΎΠ»Ρ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡΡΡ Node ΡΠ΅ ΠΈΠ·ΠΏΡΠ»Π½ΡΠ²Π° Π²ΡΠ΅ΠΊΠΈ ΠΏΡΡ, ΠΊΠΎΠ³Π°ΡΠΎ ΡΠ΅ ΠΈΠ·Π²ΡΡΡΠ²Π° ΠΊΠ°ΡΡΠΈΠ½Π³ ΠΊΡΠΌ 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.
ΠΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π½Π°ΠΏΡΠ°Π²ΠΈΡΠ΅ Π΄ΠΎΡΡΠΎΡΡΠ²Π°Π½Π΅ Π½Π° ΡΠ°ΠΉΠ»Π° Ρ ΠΊΠ»Π°ΡΠΎΠ²Π΅: . ./my-classes.ps1. Π’ΠΎΠ²Π° ΡΠ΅ ΠΈΠ·ΠΏΡΠ»Π½ΠΈ my-classes.ps1 Π² ΡΠ΅ΠΊΡΡΠ°ΡΠ° Π²ΠΈ ΠΎΠ±Π»Π°ΡΡ Π½Π° Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡ ΠΈ ΡΠ΅ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈ Π²ΡΠΈΡΠΊΠΈ ΠΊΠ»Π°ΡΠΎΠ²Π΅ ΠΎΡ ΡΠ°ΠΉΠ»Π°.
ΠΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΡΡΠ·Π΄Π°Π΄Π΅ΡΠ΅ ΠΌΠΎΠ΄ΡΠ» Powershell, ΠΊΠΎΠΉΡΠΎ Π΅ΠΊΡΠΏΠΎΡΡΠΈΡΠ° Π²ΡΠΈΡΠΊΠΈ Π²Π°ΡΠΈ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΠΊΠΈ API (ΠΊΠΎΠΌΠ°Π½Π΄Π»Π΅ΡΠΈ) ΠΈ Π΄Π° Π·Π°Π΄Π°Π΄Π΅ΡΠ΅ ΠΏΡΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π°ΡΠ° 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ΠΠ°ΠΊΠ²ΠΎ ΠΎΡΠ΅ Π΄Π° ΠΏΡΠΎΡΠ΅ΡΠ΅ΡΠ΅
ΠΠ·ΡΠΎΡΠ½ΠΈΠΊ: habr.com
