ΠΡ Π₯Π°Π±Ρ! ΠΠΈ Π³ΠΎ ΠΏΡΠ΅Π·Π΅Π½ΡΠΈΡΠ°ΠΌ ΠΏΡΠ΅Π²ΠΎΠ΄ΠΎΡ Π½Π° ΡΡΠ°ΡΠΈΡΠ°ΡΠ°
ΠΠ΅ΡΡΠ²Π°ΠΌ Π΄Π΅ΠΊΠ° Π½Π΅ Π΅ ΠΎΠΊΡΠΈΠΌΠΎΡΠΎΠ½β
ΠΠ±ΡΠ΅ΠΊΡΠ½ΠΎ-ΠΎΡΠΈΠ΅Π½ΡΠΈΡΠ°Π½ΠΈΡΠ΅ ΠΈ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»Π½ΠΈΡΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ°ΡΠΊΠΈ ΠΏΠ°ΡΠ°Π΄ΠΈΠ³ΠΌΠΈ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΈΠ·Π³Π»Π΅Π΄Π°Π°Ρ Π½Π΅ΡΠΎΠ³Π»Π°ΡΠ½ΠΈ Π΅Π΄Π½Π° ΡΠΎ Π΄ΡΡΠ³Π°, Π½ΠΎ ΠΈ Π΄Π²Π΅ΡΠ΅ ΡΠ΅ ΠΏΠΎΠ΄Π΅Π΄Π½Π°ΠΊΠ²ΠΎ ΠΏΠΎΠ΄Π΄ΡΠΆΠ°Π½ΠΈ Π²ΠΎ 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
}
ΠΠΎΠΊΡΠ°Ρ ΡΠΎΠ°, ΠΊΠ°ΡΡΠΈΠ½Π³ ΠΏΠΎΠΌΠ°Π³Π° Π΄Π° ΡΠ΅ Π΄ΠΎΠ±ΠΈΠ΅ ΡΠΈΡΡ ΠΈΠ·Π»Π΅Π·. Π‘ΠΏΠΎΡΠ΅Π΄Π΅ΡΠ΅ Π³ΠΎ ΠΈΠ·Π»Π΅Π·ΠΎΡ ΠΎΠ΄ Π½ΠΈΠ·Π°ΡΠ° Π·Π° Ρ Π°ΡΡΠ°Π±ΠΈ 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
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'"
Π€ΡΠ»Π°ΡΡΠ΅ ΡΠ΅ΡΠΈΡΠ°Π»ΠΈΠ·ΠΈΡΠ°Π½ΠΈ ΡΠ»ΡΡΠ°ΠΈ
ΠΠΈΡΡΠ°ΡΠ° ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡΠ²Π° ΡΠΈΠ³ΡΡΠ½Π° Π΄Π΅ΡΠ΅ΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡΠ°. ΠΡΠΈΠΌΠ΅ΡΠΈΡΠ΅ ΠΏΠΎΠ΄ΠΎΠ»Ρ Π½Π΅ΠΌΠ° Π΄Π° ΡΡΠΏΠ΅Π°Ρ Π°ΠΊΠΎ ΠΏΠΎΠ΄Π°ΡΠΎΡΠΈΡΠ΅ Π½Π΅ Π³ΠΈ ΠΈΡΠΏΠΎΠ»Π½ΡΠ²Π°Π°Ρ Π½Π°ΡΠΈΡΠ΅ ΡΠΏΠ΅ΡΠΈΡΠΈΠΊΠ°ΡΠΈΡΠ° Π²ΠΎ ΠΠ»Π°ΡΡΠ΅ΡΠΎΡ
# ΠΠ°Π»ΠΈΠ΄Π°ΡΠΈΡ ΡΠ΅ΡΠΈΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½ΡΡ
Π΄Π°Π½Π½ΡΡ
[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) ΠΈ Π΄Π° ΡΠ° ΠΏΠΎΡΡΠ°Π²ΠΈΡΠ΅ ΠΏΡΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π°ΡΠ° 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
Π¨ΡΠΎ Π΄ΡΡΠ³ΠΎ Π΄Π° ΡΠ΅ ΠΏΡΠΎΡΠΈΡΠ°
ΠΠ·Π²ΠΎΡ: www.habr.com