L'output testuale dei comandi nella finestra dell'interprete PowerShell è solo un modo per visualizzare le informazioni in una forma adatta alla percezione umana. Anzi mercoledì
Sommario:
Oggetti in PowerShell
Ricordiamo che un oggetto è un insieme di campi dati (proprietà, eventi, ecc.) e metodi per elaborarli (metodi). La relativa struttura è specificata da un tipo, in genere basato sulle classi usate nella piattaforma .NET Core unificata. È anche possibile lavorare con oggetti COM, CIM (WMI) e ADSI. Proprietà e metodi sono necessari per eseguire varie azioni sui dati; inoltre, in PowerShell, gli oggetti possono essere passati come argomenti a funzioni e cmdlet, assegnati i loro valori a variabili e c'è anche
Visualizzazione della struttura degli oggetti
Ad esempio, eseguiamo il cmdlet Get-Process, che consente di ottenere informazioni sui processi in esecuzione nel sistema:
Verranno visualizzati alcuni dati di testo formattati che non danno alcuna idea sulle proprietà degli oggetti restituiti e sui loro metodi. Per mettere a punto l'output, dobbiamo imparare come esaminare la struttura degli oggetti e il cmdlet Get-Member ci aiuterà in questo:
Get-Process | Get-Member
Qui vediamo già il tipo e la struttura e con l'aiuto di parametri aggiuntivi possiamo, ad esempio, visualizzare solo le proprietà dell'oggetto incluso nell'input:
Get-Process | Get-Member -MemberType Property
Questa conoscenza sarà necessaria per risolvere problemi di amministrazione in modo interattivo o per scrivere i propri script: ad esempio, per ottenere informazioni sui processi bloccati utilizzando la proprietà Responding.
Filtraggio degli oggetti
PowerShell consente il passaggio degli oggetti che soddisfano una determinata condizione attraverso una pipeline:
Where-Object { блок сценария }
Il risultato dell'esecuzione del blocco di script tra parentesi deve essere un valore booleano. Se è vero ($true), l'oggetto immesso nel cmdlet Where-Object verrà passato lungo la pipeline, altrimenti ($false) verrà eliminato. Ad esempio, visualizziamo un elenco di servizi Windows Server arrestati, ad es. quelli la cui proprietà Status è impostata su “Stopped”:
Get-Service | Where-Object {$_.Status -eq "Stopped"}
Anche qui vediamo una rappresentazione testuale, ma se si vuole capire la tipologia e la struttura interna degli oggetti che transitano nella pipeline non è difficile:
Get-Service | Where-Object {$_.Status -eq "Stopped"} | Get-Member
Ordinamento di oggetti
Durante l'elaborazione in pipeline degli oggetti, spesso è necessario ordinarli. Al cmdlet Sort-Object vengono passati i nomi delle proprietà (chiavi di ordinamento) e restituisce gli oggetti ordinati in base ai relativi valori. È facile ordinare l'output dei processi in esecuzione in base al tempo impiegato dalla CPU (proprietà della CPU):
Get-Process | Sort-Object –Property cpu
Il parametro -Property può essere omesso quando si chiama il cmdlet Sort-Object; viene utilizzato per impostazione predefinita. Per l'ordinamento inverso, utilizzare il parametro -Descending:
Get-Process | Sort-Object cpu -Descending
Selezione degli oggetti e delle loro parti
Il cmdlet Select-Object consente di selezionare un numero specifico di oggetti all'inizio o alla fine di una pipeline utilizzando i parametri -First o -Last. Con il suo aiuto puoi selezionare singoli oggetti o determinate proprietà e anche creare nuovi oggetti basati su di essi. Diamo un'occhiata a come funziona il cmdlet utilizzando semplici esempi.
Il seguente comando visualizza informazioni sui 10 processi che consumano la quantità massima di RAM (proprietà WS):
Get-Process | Sort-Object WS -Descending | Select-Object -First 10
Puoi selezionare solo alcune proprietà degli oggetti che passano attraverso la pipeline e crearne di nuove in base ad esse:
Get-Process | Select-Object ProcessName, Id -First 1
Come risultato del funzionamento della pipeline, riceveremo un nuovo oggetto, la cui struttura sarà diversa da quella restituita dal cmdlet Get-Process. Verifichiamolo utilizzando Get-Member:
Get-Process | Select-Object ProcessName, Id -First 1 | Get-Member
Da notare che Select-Object restituisce un singolo oggetto (-First 1) che presenta solo due dei campi da noi specificati: i loro valori sono stati copiati dal primo oggetto passato in pipeline dal cmdlet Get-Process. Uno dei modi per creare oggetti negli script PowerShell si basa sull'utilizzo di Select-Object:
$obj = Get-Process | Select-Object ProcessName, Id -First 1
$obj.GetType()
Utilizzando Select-Object, è possibile aggiungere proprietà calcolate agli oggetti che devono essere rappresentati come
Get-Process | Select-Object -Property ProcessName, @{Name="StartTime"; Expression = {$_.StartTime.Minute}}
Diamo un'occhiata alla struttura degli oggetti che passano attraverso il trasportatore:
Get-Process | Select-Object -Property ProcessName, @{Name="StartTime"; Expression = {$_.StartTime.Minute}} | Get-Member
ForEach-Object, Group-Object e Measure-Object
Sono disponibili altri cmdlet per lavorare con gli oggetti. Ad esempio, parliamo dei tre più utili:
PerOgni-Oggetto ti consente di eseguire il codice PowerShell per ogni oggetto nella pipeline:
ForEach-Object { блок сценария }
Oggetto-gruppo raggruppa gli oggetti in base al valore della proprietà:
Group-Object PropertyName
Se lo esegui con il parametro -NoElement, puoi scoprire il numero di elementi nei gruppi.
Misura-Oggetto aggrega vari parametri di riepilogo in base ai valori dei campi oggetto nella pipeline (calcola la somma e trova anche il valore minimo, massimo o medio):
Measure-Object -Property PropertyName -Minimum -Maximum -Average -Sum
In genere, i cmdlet discussi vengono utilizzati in modo interattivo e spesso vengono creati negli script.
Creazione di oggetti .NET e COM (New-Object)
Sono disponibili molti componenti software con interfacce .NET Core e COM utili per gli amministratori di sistema. Utilizzando la classe System.Diagnostics.EventLog è possibile gestire i registri di sistema direttamente da Windows PowerShell. Diamo un'occhiata a un esempio di creazione di un'istanza di questa classe utilizzando il cmdlet New-Object con il parametro -TypeName:
New-Object -TypeName System.Diagnostics.EventLog
Poiché non abbiamo specificato un registro eventi specifico, l'istanza risultante della classe non contiene dati. Per modificare ciò, è necessario chiamare uno speciale metodo di costruzione durante la sua creazione utilizzando il parametro -ArgumentList. Se vogliamo accedere al log dell'applicazione, dobbiamo passare la stringa "Application" come argomento al costruttore:
$AppLog = New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application
$AppLog
Tieni presente che abbiamo salvato l'output del comando nella variabile $AppLog. Sebbene le pipeline siano comunemente utilizzate in modalità interattiva, la scrittura di script spesso richiede il mantenimento di un riferimento a un oggetto. Inoltre, le classi principali di .NET Core sono contenute nello spazio dei nomi System: PowerShell per impostazione predefinita cerca i tipi specificati al suo interno, quindi scrivere Diagnostics.EventLog anziché System.Diagnostics.EventLog è abbastanza corretto.
Per lavorare con il registro, è possibile utilizzare i metodi appropriati:
$AppLog | Get-Member -MemberType Method
Diciamo che viene cancellato dal metodo Clear() se ci sono diritti di accesso:
$AppLog.Clear()
Il cmdlet New-Object viene utilizzato anche per lavorare con i componenti COM. Ce ne sono molti: dalle librerie fornite con lo script server di Windows alle applicazioni ActiveX, come Internet Explorer. Per creare un oggetto COM, è necessario impostare il parametro -ComObject con il ProgId programmatico della classe desiderata:
New-Object -ComObject WScript.Shell
New-Object -ComObject WScript.Network
New-Object -ComObject Scripting.Dictionary
New-Object -ComObject Scripting.FileSystemObject
Per creare i propri oggetti con una struttura arbitraria, l'utilizzo di New-Object sembra troppo arcaico e macchinoso; questo cmdlet viene utilizzato per lavorare con componenti software esterni a PowerShell. Nei prossimi articoli questo argomento verrà discusso in modo più approfondito. Oltre agli oggetti .NET e COM, esploreremo anche gli oggetti CIM (WMI) e ADSI.
Chiamata di metodi statici
Non è possibile creare un'istanza di alcune classi .NET Core, inclusi System.Environment e System.Math. Sono
[System.Environment] | Get-Member
Per visualizzare solo i membri statici, chiama Get-Member con il parametro -Static (nota il tipo di oggetto):
[System.Environment] | Get-Member -Static
Per accedere a proprietà e metodi statici, utilizzare due due punti consecutivi anziché un punto dopo il valore letterale:
[System.Environment]::OSVersion
O
$test=[System.Math]::Sqrt(25)
$test
$test.GetType()
Digitare PSCustomObject
Tra i numerosi tipi di dati disponibili in PowerShell, vale la pena menzionare PSCustomObject, progettato per archiviare oggetti con una struttura arbitraria. Creare un oggetto di questo tipo utilizzando il cmdlet New-Object è considerato un modo classico, ma complicato e obsoleto:
$object = New-Object –TypeName PSCustomObject -Property @{Name = 'Ivan Danko';
City = 'Moscow';
Country = 'Russia'}
Diamo un'occhiata alla struttura dell'oggetto:
$object | Get-Member
A partire da PowerShell 3.0, è disponibile un'altra sintassi:
$object = [PSCustomObject]@{Name = 'Ivan Danko';
City = 'Moscow';
Country = 'Russia'
}
È possibile accedere ai dati in uno dei modi equivalenti:
$object.Name
$object.'Name'
$value = 'Name'
$object.$value
Ecco un esempio di conversione di una tabella hash esistente in un oggetto:
$hash = @{'Name'='Ivan Danko'; 'City'='Moscow'; 'Country'='Russia'}
$hash.GetType()
$object = [pscustomobject]$hash
$object.GetType()
Uno degli svantaggi degli oggetti di questo tipo è che l'ordine delle loro proprietà può cambiare. Per evitare ciò, è necessario utilizzare l'attributo [ordinato]:
$object = [PSCustomObject][ordered]@{Name = 'Ivan Danko';
City = 'Moscow';
Country = 'Russia'
}
Esistono altre opzioni per creare un oggetto: sopra abbiamo visto l'utilizzo del cmdlet
$object | Add-Member –MemberType NoteProperty –Name Age –Value 33
$object | Get-Member
Il cmdlet Add-Member consente di aggiungere non solo proprietà, ma anche metodi a un oggetto $ creato in precedenza utilizzando il costrutto "-MemberType ScriptMethod":
$ScriptBlock = {
# код
}
$object | Add-Member -Name "MyMethod" -MemberType ScriptMethod -Value $ScriptBlock
$object | Get-Member
Tieni presente che abbiamo utilizzato la variabile $ScriptBlock di tipo ScriptBlock per memorizzare il codice per il nuovo metodo.
Per rimuovere le proprietà, utilizzare il metodo corrispondente:
$object.psobject.properties.remove('Name')
Creazione delle tue classi
PowerShell 5.0 ha introdotto la possibilità di definire
class MyClass
{
# тело класса
}
Si tratta di un vero tipo .NET Core, con un corpo che ne descrive le proprietà, i metodi e altri elementi. Diamo un'occhiata a un esempio di definizione della classe più semplice:
class MyClass
{
[string]$Name
[string]$City
[string]$Country
}
Per creare un oggetto (istanza della classe), utilizzare il cmdlet
$object = New-Object -TypeName MyClass
o
$object = [MyClass]::new()
Analizziamo la struttura dell'oggetto:
$object | Get-Member
Non dimenticare l'ambito: non puoi fare riferimento a un nome di tipo come una stringa o utilizzare un tipo letterale al di fuori dello script o del modulo in cui è definita la classe. In questo caso, le funzioni possono restituire istanze di classe (oggetti) che saranno accessibili all'esterno del modulo o dello script.
Dopo aver creato l'oggetto, inserisci le sue proprietà:
$object.Name = 'Ivan Danko'
$object.City = 'Moscow'
$object.Country = 'Russia'
$object
Tieni presente che la descrizione della classe specifica non solo i tipi di proprietà, ma anche i loro valori predefiniti:
class Example
{
[string]$Name = 'John Doe'
}
La descrizione di un metodo di classe assomiglia alla descrizione di una funzione, ma senza utilizzare la parola funzione. Come in una funzione, i parametri vengono passati ai metodi se necessario:
class MyClass
{
[string]$Name
[string]$City
[string]$Country
#описание метода
Smile([bool]$param1)
{
If($param1) {
Write-Host ':)'
}
}
}
Ora il rappresentante della nostra classe può sorridere:
$object = [MyClass]::new()
$object.Smile($true)
I metodi possono essere sovraccaricati; inoltre, una classe ha
class MyClass2 : MyClass
{
#тело нового класса, базовым для которого является MyClass
}
[MyClass2]::new().Smile($true)
La nostra descrizione dell'utilizzo degli oggetti in PowerShell non è certo esaustiva. Nelle pubblicazioni successive cercheremo di approfondirlo con esempi pratici: il quinto articolo della serie sarà dedicato ai temi dell'integrazione di PowerShell con componenti software di terze parti. Le parti precedenti possono essere trovate ai link seguenti.
Fonte: habr.com