De tekstuitvoer van opdrachten in het PowerShell-interpretervenster is slechts een manier om informatie weer te geven in een vorm die geschikt is voor menselijke waarneming. Eigenlijk woensdag
авление:
Objecten in PowerShell
Laten we niet vergeten dat een object een verzameling gegevensvelden is (eigenschappen, gebeurtenissen, enz.) en methoden om deze te verwerken (methoden). De structuur wordt gespecificeerd door een type, dat meestal is gebaseerd op klassen die worden gebruikt in het verenigde .NET Core-platform. Ook is het mogelijk om met COM-, CIM (WMI) en ADSI-objecten te werken. Eigenschappen en methoden zijn nodig om verschillende acties op gegevens uit te voeren; bovendien kunnen objecten in PowerShell als argumenten worden doorgegeven aan functies en cmdlets, hun waarden worden toegewezen aan variabelen, en er is ook
De structuur van objecten bekijken
Laten we bijvoorbeeld de cmdlet Get-Process uitvoeren, waarmee u informatie kunt verkrijgen over de processen die in het systeem worden uitgevoerd:
Het zal enkele opgemaakte tekstgegevens weergeven die geen enkel idee geven over de eigenschappen van de geretourneerde objecten en hun methoden. Om de uitvoer te verfijnen, moeten we leren hoe we de structuur van objecten kunnen onderzoeken, en de Get-Member cmdlet zal ons hierbij helpen:
Get-Process | Get-Member
Hier zien we al het type en de structuur, en met behulp van aanvullende parameters kunnen we bijvoorbeeld alleen de eigenschappen weergeven van het object dat in de invoer is opgenomen:
Get-Process | Get-Member -MemberType Property
Deze kennis is nodig om beheerproblemen interactief op te lossen of om uw eigen scripts te schrijven: om bijvoorbeeld informatie te verkrijgen over vastgelopen processen met behulp van de eigenschap Responding.
Objecten filteren
Met PowerShell kunnen objecten die aan een bepaalde voorwaarde voldoen, door een pijplijn worden gevoerd:
Where-Object { блок сценария }
Het resultaat van het uitvoeren van het scriptblok tussen haakjes moet een Booleaanse waarde zijn. Als het waar is ($true), wordt het object dat wordt ingevoerd in de Where-Object-cmdlet langs de pijplijn doorgegeven, anders ($false) wordt het verwijderd. Laten we bijvoorbeeld een lijst met gestopte Windows Server-services weergeven, d.w.z. degenen waarvan de Status-eigenschap is ingesteld op "Gestopt":
Get-Service | Where-Object {$_.Status -eq "Stopped"}
Ook hier zien we een tekstuele weergave, maar als je het type en de interne structuur wilt begrijpen van de objecten die door de pijplijn gaan, is dat niet moeilijk:
Get-Service | Where-Object {$_.Status -eq "Stopped"} | Get-Member
Objecten sorteren
Bij pijplijnverwerking van objecten is het vaak nodig om ze te sorteren. Aan de cmdlet Sort-Object worden de namen van eigenschappen (sorteersleutels) doorgegeven en worden objecten geretourneerd, gerangschikt op hun waarden. Het is eenvoudig om de uitvoer van actieve processen te sorteren op bestede CPU-tijd (cpu-eigenschap):
Get-Process | Sort-Object –Property cpu
De parameter -Property kan worden weggelaten bij het aanroepen van de cmdlet Sort-Object; deze wordt standaard gebruikt. Gebruik voor omgekeerd sorteren de parameter -Descending:
Get-Process | Sort-Object cpu -Descending
Objecten en hun onderdelen selecteren
Met de cmdlet Select-Object kunt u een specifiek aantal objecten aan het begin of einde van een pijplijn selecteren met behulp van de para meters -First of -Last. Met zijn hulp kunt u afzonderlijke objecten of bepaalde eigenschappen selecteren en op basis daarvan ook nieuwe objecten maken. Laten we eens kijken hoe de cmdlet werkt aan de hand van eenvoudige voorbeelden.
De volgende opdracht geeft informatie weer over de 10 processen die de maximale hoeveelheid RAM verbruiken (WS-eigenschap):
Get-Process | Sort-Object WS -Descending | Select-Object -First 10
U kunt alleen bepaalde eigenschappen selecteren van objecten die door de pijplijn gaan en op basis daarvan nieuwe maken:
Get-Process | Select-Object ProcessName, Id -First 1
Als gevolg van de werking van de pijplijn ontvangen we een nieuw object, waarvan de structuur zal verschillen van de structuur die wordt geretourneerd door de Get-Process-cmdlet. Laten we dit verifiëren met Get-Member:
Get-Process | Select-Object ProcessName, Id -First 1 | Get-Member
Houd er rekening mee dat Select-Object een enkel object (-First 1) retourneert dat slechts twee van de velden bevat die we hebben opgegeven: hun waarden zijn gekopieerd van het eerste object dat door de Get-Process-cmdlet in de pijplijn is doorgegeven. Een van de manieren om objecten in PowerShell-scripts te maken is gebaseerd op het gebruik van Select-Object:
$obj = Get-Process | Select-Object ProcessName, Id -First 1
$obj.GetType()
Met Select-Object kunt u berekende eigenschappen toevoegen aan objecten die moeten worden weergegeven als
Get-Process | Select-Object -Property ProcessName, @{Name="StartTime"; Expression = {$_.StartTime.Minute}}
Laten we eens kijken naar de structuur van objecten die door de transportband gaan:
Get-Process | Select-Object -Property ProcessName, @{Name="StartTime"; Expression = {$_.StartTime.Minute}} | Get-Member
Voor elk object, groepsobject en meetobject
Er zijn andere cmdlets voor het werken met objecten. Laten we het als voorbeeld hebben over de drie meest bruikbare:
Voor elk-object Hiermee kunt u PowerShell-code uitvoeren voor elk object in de pijplijn:
ForEach-Object { блок сценария }
Groepsobject groepeert objecten op eigenschapswaarde:
Group-Object PropertyName
Als u het uitvoert met de parameter -NoElement, kunt u het aantal elementen in de groepen achterhalen.
Maatregel-Object verzamelt verschillende samenvattingsparameters op objectveldwaarden in de pijplijn (berekent de som en vindt ook de minimum-, maximum- of gemiddelde waarde):
Measure-Object -Property PropertyName -Minimum -Maximum -Average -Sum
Normaal gesproken worden de besproken cmdlets interactief gebruikt en vaak in scripts gemaakt.
.NET- en COM-objecten maken (New-Object)
Er zijn veel softwarecomponenten met .NET Core- en COM-interfaces die handig zijn voor systeembeheerders. Met de klasse System.Diagnostics.EventLog kunt u systeemlogboeken rechtstreeks vanuit Windows PowerShell beheren. Laten we eens kijken naar een voorbeeld van het maken van een exemplaar van deze klasse met behulp van de New-Object-cmdlet met de parameter -TypeName:
New-Object -TypeName System.Diagnostics.EventLog
Omdat we geen specifiek gebeurtenislogboek hebben opgegeven, bevat de resulterende instantie van de klasse geen gegevens. Om dit te veranderen, moet u tijdens het maken een speciale constructormethode aanroepen met behulp van de parameter -ArgumentList. Als we toegang willen krijgen tot het applicatielogboek, moeten we de string "Applicatie" als argument doorgeven aan de constructor:
$AppLog = New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application
$AppLog
Houd er rekening mee dat we de uitvoer van de opdracht hebben opgeslagen in de variabele $AppLog. Hoewel pijplijnen vaak in de interactieve modus worden gebruikt, vereist het schrijven van scripts vaak een verwijzing naar een object. Bovendien zijn de kernklassen van .NET Core opgenomen in de systeemnaamruimte: PowerShell zoekt standaard naar gespecificeerde typen daarin, dus het schrijven van Diagnostics.EventLog in plaats van System.Diagnostics.EventLog is volkomen correct.
Om met het logboek te werken, kunt u de juiste methoden gebruiken:
$AppLog | Get-Member -MemberType Method
Laten we zeggen dat het wordt gewist door de Clear()-methode als er toegangsrechten zijn:
$AppLog.Clear()
De New-Object-cmdlet wordt ook gebruikt om met COM-componenten te werken. Er zijn er nogal wat - van de bibliotheken die bij de Windows-scriptserver worden geleverd tot ActiveX-toepassingen, zoals Internet Explorer. Om een COM-object te maken, moet u de parameter -ComObject instellen met de programmatische ProgId van de gewenste klasse:
New-Object -ComObject WScript.Shell
New-Object -ComObject WScript.Network
New-Object -ComObject Scripting.Dictionary
New-Object -ComObject Scripting.FileSystemObject
Om uw eigen objecten met een willekeurige structuur te maken, lijkt het gebruik van New-Object te archaïsch en omslachtig; deze cmdlet wordt gebruikt om te werken met softwarecomponenten buiten PowerShell. In toekomstige artikelen zal dit onderwerp in meer detail worden besproken. Naast .NET- en COM-objecten zullen we ook CIM (WMI) en ADSI-objecten verkennen.
Statische methoden aanroepen
Sommige .NET Core-klassen kunnen niet worden geïnstantieerd, inclusief System.Environment en System.Math. Zij zijn
[System.Environment] | Get-Member
Als u alleen statische leden wilt bekijken, roept u Get-Member aan met de parameter -Static (let op het objecttype):
[System.Environment] | Get-Member -Static
Om toegang te krijgen tot statische eigenschappen en methoden, gebruikt u twee opeenvolgende dubbele punten in plaats van een punt na de letterlijke:
[System.Environment]::OSVersion
Of
$test=[System.Math]::Sqrt(25)
$test
$test.GetType()
Typ PSCustomObject
Onder de vele gegevenstypen die beschikbaar zijn in PowerShell, is PSCustomObject de moeite waard, ontworpen voor het opslaan van objecten met een willekeurige structuur. Het maken van een dergelijk object met behulp van de New-Object-cmdlet wordt als een klassieke, maar omslachtige en verouderde manier beschouwd:
$object = New-Object –TypeName PSCustomObject -Property @{Name = 'Ivan Danko';
City = 'Moscow';
Country = 'Russia'}
Laten we eens kijken naar de structuur van het object:
$object | Get-Member
Vanaf PowerShell 3.0 is er een andere syntaxis beschikbaar:
$object = [PSCustomObject]@{Name = 'Ivan Danko';
City = 'Moscow';
Country = 'Russia'
}
U kunt op een van de gelijkwaardige manieren toegang krijgen tot de gegevens:
$object.Name
$object.'Name'
$value = 'Name'
$object.$value
Hier is een voorbeeld van het converteren van een bestaande hashtabel naar een object:
$hash = @{'Name'='Ivan Danko'; 'City'='Moscow'; 'Country'='Russia'}
$hash.GetType()
$object = [pscustomobject]$hash
$object.GetType()
Een van de nadelen van dit soort objecten is dat de volgorde van hun eigenschappen kan veranderen. Om dit te voorkomen, moet u het [ordered] attribuut gebruiken:
$object = [PSCustomObject][ordered]@{Name = 'Ivan Danko';
City = 'Moscow';
Country = 'Russia'
}
Er zijn andere opties voor het maken van een object: hierboven hebben we gekeken naar het gebruik van de cmdlet
$object | Add-Member –MemberType NoteProperty –Name Age –Value 33
$object | Get-Member
Met de cmdlet Add-Member kunt u niet alleen eigenschappen, maar ook methoden toevoegen aan een eerder gemaakt $object met behulp van de constructie '-MemberType ScriptMethod':
$ScriptBlock = {
# код
}
$object | Add-Member -Name "MyMethod" -MemberType ScriptMethod -Value $ScriptBlock
$object | Get-Member
Houd er rekening mee dat we de variabele $ScriptBlock van het type ScriptBlock hebben gebruikt om de code voor de nieuwe methode op te slaan.
Gebruik de overeenkomstige methode om eigenschappen te verwijderen:
$object.psobject.properties.remove('Name')
Je eigen klassen creëren
PowerShell 5.0 introduceerde de mogelijkheid om te definiëren
class MyClass
{
# тело класса
}
Dit is een echt .NET Core-type, met een hoofdtekst die de eigenschappen, methoden en andere elementen ervan beschrijft. Laten we een voorbeeld bekijken van het definiëren van de eenvoudigste klasse:
class MyClass
{
[string]$Name
[string]$City
[string]$Country
}
Gebruik de cmdlet om een object (klasse-instantie) te maken
$object = New-Object -TypeName MyClass
of
$object = [MyClass]::new()
Laten we de structuur van het object analyseren:
$object | Get-Member
Vergeet de reikwijdte niet: u kunt niet naar een typenaam verwijzen als een tekenreeks of een letterlijk type gebruiken buiten het script of de module waarin de klasse is gedefinieerd. In dit geval kunnen functies klasse-instanties (objecten) retourneren die toegankelijk zijn buiten de module of het script.
Nadat u het object heeft gemaakt, vult u de eigenschappen in:
$object.Name = 'Ivan Danko'
$object.City = 'Moscow'
$object.Country = 'Russia'
$object
Merk op dat de klassebeschrijving niet alleen de eigenschapstypen specificeert, maar ook hun standaardwaarden:
class Example
{
[string]$Name = 'John Doe'
}
De beschrijving van een klassemethode lijkt op de beschrijving van een functie, maar zonder het functiewoord te gebruiken. Net als bij een functie worden indien nodig parameters doorgegeven aan methoden:
class MyClass
{
[string]$Name
[string]$City
[string]$Country
#описание метода
Smile([bool]$param1)
{
If($param1) {
Write-Host ':)'
}
}
}
Nu kan de vertegenwoordiger van onze klas glimlachen:
$object = [MyClass]::new()
$object.Smile($true)
Methoden kunnen overbelast raken; bovendien is een klasse dat ook
class MyClass2 : MyClass
{
#тело нового класса, базовым для которого является MyClass
}
[MyClass2]::new().Smile($true)
Onze beschrijving van het werken met objecten in PowerShell is nauwelijks uitputtend. In de volgende publicaties zullen we proberen het te verdiepen met praktische voorbeelden: het vijfde artikel in de serie zal gewijd zijn aan de problemen van de integratie van PowerShell met softwarecomponenten van derden. Eerdere delen zijn te vinden via onderstaande links.
Bron: www.habr.com