Introducció a Powershell: cmdlets i objectes
Aquesta pàgina és una breu introducció al sistema d'scripting de Windows; se supposa que el lector té coneixements bàsics de programació a nivell de variables, paràmetres i estructure de control bàsiques.Què és i per què serveix el Windows PowerShell?
- És una interfície de consola (comandaments) per Windows molt més avançada que el seu predecessor cmd (command)
- Està destinat a administradors de sistemes amb la finalitat principal d’automatitzar tasques
- Es poden crear scripts powershell, a part d’utilitzar-se com a simple consola de comandes
- La seva característica principal és que les seves comandes són orientades a objectes, això vol dir que es veu el sistema operatiu com una col·lecció d'objectes virtuals; per exemple un procés del sistema és un objecte, i una carpeta del sistema de fitxers un altre objecte. Cada objecte té unes propietats i unes funcions, per exemple són propietats de l'objecte carpeta el seu nom i la seva data de creació, i són funcions el renombrar-la o mostrar el seu contingut.
- Powershell (abreujadament PS) s’ inclou en Windows a partir del Windows Vista
![]() |
Fig. 1: finestra de comandaments del Powershell |
Comandaments del Powershell: cmdlets
Cmdlet és un nom creat pels desenvolupadors de Windows PowerShell. Són les comandes que es poden utilitzar en PowerShell, diferents de les comandes tradicionals del cmd.exe![]() |
Fig. 2: els cmdlets get-process (informació d'un procés) i end-process (finalitzar procés) |
Get-command –commandtype cmdlet
Per consultar el manual d’ajuda d’un cmdlet:
Get-help cmdlet
Exemple: Get-help stop-process
Podem crear els anomenats alias, que permeten assignar noms de dreceres (“shortcuts” ) als cmdlets; per exemple, anomenar gh al cmdlet Get-help: gh stop-process)
Els cmdlets Get-item i Get-member
Get-member és un altre cmdlet que ens permet obtenir totes les propietats i mètodes d'un objecte al que hem vinculat la variable. Aquest objecte pot ser qualsevol, fins i tot un altre cmdlet. La forma de usar-lo es amb el símbol "|" per unir l'objecte amb el get-member, el resultat és un llistat complerta de propietats:
![]() |
Fig.3: propietats del cmdlet get-process, obtingudes usant get-member |
El cmdlet Get-item permet assignar (o vincular) una variable de Powershell amb un objecte; les variables en PS comencen sempre per $. Des del moment que assignem la variable a l'objecte, totes les accions que efectuem amb la variable afectaran a l'objecte (estan vinculats).
Exemple: amb Get-item vinculem una variable amb l'objecte que representa la carpeta C:\windows. A continuació, podem veure les seves propietats i mètodes amb Get-member.
![]() |
Fig.4: assignació d'una variable a un objecte (carpeta) i mostrar les propietats |
Les propietats dels objectes
Cada objecte té una llista de propietats, i cada propietat te un valor; per veure el valor d'una propietat simplement escribim el seu nom. Per exemple, en la fig.4 veiem que l'objecte carpeta te la propietat Mode, per veure el seu valor:PS C:\Users\Administrador> $carpeta.mode
d----
PS C:\Users\Administrador>
La línia d---- indica que l'objecte és un fitxer de tipus "directori" (d). Un altre exemple amb la propietat name:
PS C:\Users\Administrador> $carpeta.nameI un darrer exemple amb la propietat que ens dona la data de creació de la carpeta:
system32
PS C:\Users\Administrador>
PS C:\Users\Administrador> $carpeta.CreationTime
martes, 14 de julio de 2009 4:37:07
Crear scripts (guions) de comandaments Powershell
Nivells de seguretat
Un script és una seqüencia de comandaments, és a dir, un programa.Per defecte, l’execució d’scripts PS està deshabilitada per seguretat, degut a que PS és molt potent, és pot fer qualsevol cosa amb ell si tens drets d'execució.
Hi ha 4 nivells d’ execució d’scripts:
- Restricted: no es pot executar scripts
- AllSigned: tots els scripts que s’executen han d’estar signats digitalment
- RemoteSigned: tots els scripts descarregats d’internet han d’estar signats per un autor de confiança
- Unrestricted: es poden executar tots els scripts
PS C:\Users> get-executionpolicy
Unrestricted
PS C:\Users> set-executionpolicy allsigned
Cambio de directiva de ejecución
La directiva de ejecución le ayuda a protegerse de scripts en los que no confía. Si cambia dicha directiva podría exponerse a los riesgos de seguridad descritos en el tema de la Ayuda about_Execution_Policies. ¿Desea cambiar la directiva de ejecución?
[S] Sí [N] No [U] Suspender [?] Ayuda (el valor predeterminado es "S"):
PS C:\Users>
Execució de scripts PS
Es poden crear utilitzant qualsevol editor de text o amb l’entorn integrat Windows PowerShell ISE. Un script PS és un fitxer de text amb l’extensió .ps1Les diferents versions de Windows han anat incorporant noves versions de PS que fins la versió 5 han estat compatibles amb les anteriors. Els exemples d'aquesta pàgina han estat fets amb Windows 7 i PS v2; per evitar que algú executi un script específic per una versió moderna amb un PS antic només cal afegir al principi de l’script una línia amb la directiva #REQUIRES, per exemple per evitar que un script s'executi en versions anteriors a la 2a:
#REQUIRES Version 2Exemple: provem un script que modifica l'aspecte de l'antic comandament DIR. L'original mostra el llistat de fitxers i carpetes:
PS C:\Users> dir
Directorio: C:\Users
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 24/07/2017 19:47 Administrador
d---- 16/12/2016 8:06 alumne
d---- 17/01/2018 8:07 jordi
d---- 11/01/2017 13:47 prova
d-r-- 25/07/2017 20:43 Public
Fem que mostri el contingut de la carpeta que li passem com a paràmetre
formatat en colors:
$carpeta = $args[0];
Write-Host ("Llistat de la carpeta $carpeta")
# recorre cada element de dins la carpeta
foreach ($i in Get-Childitem $carpeta) {
if ($i.mode.substring(0,1) -eq "d") {
Write-Host $i.name -foreground "Blue"
}
else {
Write-Host $i.name -foreground "Green"
}
}
El resultat d'executar aquest script, anomenat dir2.ps1, és:
![]() |
Fig. 5: script que mostra el contingut d'una carpeta |
Comentem l'script línia a línia:
$carpeta = $args[0]; | args es un vector (o array) que conté la llista de paràmetres
que pasem a l’script quan l’executem; per exemple si cridem a
l’script així: .\dir2.ps1 jordi llavors args[0] valdrà «jordi» si el cridem \dir2.ps1 jordi pepe llavors args[0] valdrà «jordi» i args[1] valdrà «pepe», etc |
Write-Host ("Llistat de la carpeta $carpeta") | Write-Host és un cmdlet que mostra text, variables o una combinació de tots dos per pantalla. En aquest cas combina text amb la variable $carpeta |
foreach ($i in Get-Childitem $carpeta) { | La instrucció foreach és un cmdlet, especial: és una instrucció de
control del programa que a més a més recorre cada element de una llista
d’objectes. La llista d’objectes són tots els continguts dintre de la carpeta $carpeta. S'obté aquesta llista gràcies al cmdlet Get-Childitem, que retorna tots els «fills» d’una carpeta. La variable auxiliar $i va identificant-se succesivament amb tots els objectes de la llista d’objectes dins de la carpeta $carpeta |
if ($i.mode.substring(0,1) -eq "d") { | If és un altre estructura de control, s’anomena condicional.
La clau { indica que comencen una serie de instruccions
condicionals. Per cada objecte $i, la seva propietat mode retorna si es un directori o un fitxer; la funció substring extreu 1 caràcter des de la posició 0 (la primera posició) i si és igual (expressió -eq) a «d», és que l’objecte és un directori. |
Write-Host $i.name -foreground "Blue" | Escriure el nom de l’objecte (propietat name) usant el color de fons blau |
} | Finalització de la primera part de l’estructura de control if |
else { | Inici de l’estructura de control else, continuació de la if |
Write-Host $i.name -foreground "Green" | Escriure el nom de l’objecte (propietat name) usant el color de fons verd; aixó pasarà quan la primera lletra de la propietat mode no sigui igual a «d», és a dir, quan l’objecte no sigui un directori. |
} | Finalització de l’estructura de control else |
} | Finalització de l’estructura de control foreach |
Per fer comparacions en l'exemple s'ha usat l'operador lògic -eq, tenim tots aquests:
Ús de variables i constants
Les variables en PowerShell, no s’han de declarar abans d’utilitzar-les, com sí pasa en altres lleuguatges de programació. Totes van precedides del símbol $. Hi ha un conjunt de variables especials que es creen automàticament, com ara $Error que conté el llistat d'errors d'execució que han succeït, o $Args que ja hem vist que conté la llista de paràmetres que pasem a l’script quan l’executem; no podem usar variables propies nostres que es diguin igual que les especials, obtindriem un error:PS C:\Users> $error="hola"Les constants (valors amb un nom identificatiu que no han de canviar aquest valor) són tractades com a variables, amb la diferència que no canvien mai de valor, estan protegides contra canvis; es creen amb el cmdlet Set-Variable amb el paràmetre –option constant
No se puede sobrescribir la variable Error porque es de solo lectura o constante.
Exemple:
PS C:\Users> set-variable -name pc -value "localhost"Llista de variables especials (per Powershell v2):
PS C:\Users> set-variable -name tipus -value "portàtil" -option constant
PS C:\Users> $pc = "127.0.0.1"
PS C:\Users> $tipus = "torre"
No se puede sobrescribir la variable tipus porque es de solo lectura o constante.
Les variables poden ser "tipades" és a dir, restringides a contenir valors de cert tipus de dades, com ara nombres enters, un caràcter, una cadena de caràcters:
El tipus es defineix automàticament segons el contingut de la variable.
Exemple:
PS C:\Users> $a = 1; $b = 2En canvi si usem valors de tipus cadena de caràcters:
PS C:\Users> $c = $a + $b
PS C:\Users> $c
3
PS C:\Users> $a = "1"; $b = "2" ; $c = $a + $bAquest comportament automàtic està pensat per fer les coses fàcils al programador, però pot induïr a errors; quin serà el resultat de la següent operació que mescla caràcters amb nombres?
PS C:\Users> $c
12
PS C:\Users> $a = "1"; $b = 2 ; $c = $a + $bAlguns cmdlets per gestionar les variables són:
Altres variables especials són les variables d’entorn, mantingudes automàticament pel sistema operatiu.
- Per veure les variables d’entorn del sistema escrivim dir env:
- Per mostrar el valor d’una variable d’entorn, com ara la variable tmp, escrivim $env:tmp
- Per modificar el valor d’una variable d’entorn, com ara userprofile, escrivim $env:userprofile=“C:\Users\profe”
- Per afegir un valor a una variable d’entorn, com ara afegir "ps1" a la variable pathest, escrivim $env:pathext += “;ps1”
- Per consultar el valor d'una variable d’entorn especificant si és global del sistema o local de l'usuari la sintaxi és
[environment]::GetEnvironmentVariable(“nom de la variable”,”User”)
El paràmetre “User” si volem veure el valor de la variable per tots els usuaris posarem “Machine” enlloc de “User”.
- Per modificar el valor d'una variable d’entorn de forma permanent la sintaxi és
[environment]::SetEnvironmentVariable(“nom de la variable”,nou valor,”User”)
Exemple
La variable d'entorn OS és global, no té un valor concret per l'usuari que té sessió oberta, com podem comprobar:
PS C:\Users> [environment]::GetEnvironmentVariable("OS","User")Llavors podem donar un valor personalitzat a la variable OS per l'usuari que té la sessió oberta:
PS C:\Users> [environment]::GetEnvironmentVariable("OS","Machine")
Windows_NT
PS C:\Users> [environment]::SetEnvironmentVariable("OS","Windows 7","User")
Comprovem:
PS C:\Users> [environment]::GetEnvironmentVariable("OS","Machine")
Windows_NT
PS C:\Users> [environment]::GetEnvironmentVariable("OS","User")
Windows 7
Pipelines (canonades) en PS
Serveixen per passar informació d'un comandament a un altre (“canonades” de informació o “conduccions” que connecten comandaments). Per exemple si volem saber certa informació de tots els ordinadors d'un domini, podem obtenir amb Powershell una llista amb els noms dels ordinadors del domini, però després com passem aquesta llista a un altre comandament que proporcionai la informació desitjada? Connectant el resultat del primer comandament amb el segon.Les canonades ja existien en la antiga consola MSDOS, per exemple:
![]() |
Fig.6: canonada per filtrar totes les adreces de xarxa, lògiques i MACS |
PS C:\Users> get-ChildItem | format-table
Directorio: C:\Users
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 24/07/2017 19:47 Administrador
d---- 16/12/2016 8:06 alumne
d---- 17/01/2018 8:07 jordi
d---- 11/01/2017 13:47 prova
d-r-- 25/07/2017 20:43 Public
-a--- 06/04/2019 14:45 337 dir.ps1
-a--- 07/04/2019 11:35 314 dir2.ps1
PS C:\Users> get-ChildItem | format-list
Directorio: C:\Users
Name : Administrador
CreationTime : 12/01/2017 10:14:11
LastWriteTime : 24/07/2017 19:47:04
LastAccessTime : 24/07/2017 19:47:04
Name : alumne
CreationTime : 16/12/2016 8:05:56
LastWriteTime : 16/12/2016 8:06:20
LastAccessTime : 16/12/2016 8:06:20
Alguns cmdlets expressament pensats per actuar com a canonades, rebent informació d'un altre cmdlet:
Cmdlet/funció
|
Descripció
|
ConvertTo-Html
|
Converteix objectes a HTML
|
Export-Csv
|
Guarda objectes en fitxes separat per un coma
|
ForEach-Object
|
Retorna cada pipeline un darrera l’altre
|
Format-Table
|
Mostra resultats com una taula
|
Get-Unique
|
Elimina duplicats d’una llista de valors
|
Group-Object
|
Agrupa els resultats segons un criteri
|
more
|
Paginació pàgina a pàgina, amb pauses
|
Out-file
|
Escriu el resultat en un fitxer
|
Out-Host
|
Mostra el resultat pel terminal
|
Out-Host -paging
|
Mostra el resultat pel terminal per pàgines
|
Out-Null
|
Esborra el resultat
|
Out-Printer
|
Envia els resultat a una impressora
|
Select-Object
|
Filtra les propietats d’un objecte i limita
el número de resultats
|
Sort-Object
|
Ordena el resultat
|
Where-Object
|
Filtra els resultats segons un criteri
|
Alguns exemples d'ús:
PS>Dir | sort-objectEn particular, el cmdlet foreach ens permet avaluar cada element del resultat d’una comanda anterior.
PS>Dir | sort LastWriteTime –descending
PS>Dir | format-table name, lastwritetime
PS>get-process | where-object { $_.name –eq “winlogon”}
PS>get-process | where-object { $_.CPU –gt 4}
PS>get-process | where-object { $_.name –notmatch “sys”}
PS>Dir | sort-object Length | select-object Name,Length | convertTo-html | out-file report.htm
Exemples:
PS> get-process | foreach {write-output $_.Id}
PS> get-process | foreach {write-host $_.Id –f red}
PS> dir | foreach {echo $_.Name}
Les canonades són eines molt potents que obren moltes possibilitats; cal practicar una mica amb elles per adonar-se de les seves possibilitats. Per exemple, podem resoldre ràpidament problemes com els següents:
P1) Genera
una llista dels 5 processos que consumeixen més temps de CPU.
PS C:\Users> get-process | sort-object CPU -descending | select-object -first 5
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
1215 31 26160 25372 186 73,31 976 svchost
1011 32 46372 38996 326 58,11 2348 explorer
354 24 32948 17240 170 56,92 336 svchost
558 13 46256 42900 123 44,13 896 svchost
309 7 1480 4704 39 11,95 408 csrss
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
1215 31 26160 25372 186 73,31 976 svchost
1011 32 46372 38996 326 58,11 2348 explorer
354 24 32948 17240 170 56,92 336 svchost
558 13 46256 42900 123 44,13 896 svchost
309 7 1480 4704 39 11,95 408 csrss
get-process | where-object
{$_.virtualmemorysize –gt 52428800}
P3) Exporta el resultat de la consulta anterior en un fitxer amb format CSV
get-process | where-object {$_.virtualmemorysize –gt 52428800} | export-csv proc.csv
Accés al sistema de fitxers des de PS
Alguns cmdlets:Exemples
- Crear nous directoris: podem utilitzar l’alias md o la comanda New-item amb l’opció –type directory
PS> md exercici
PS> New-item exercici –type directory
- Crear nous fitxers: podem utilitzar la comanda New-item amb l’opció –type file o també redireccionaments i pipelines:
PS> New-item ex.txt –type file
PS> dir > info1.txt
PS> dir | out-file info2.txt
PS> dir | set-content info3.txt
PS> set-content info4.txt “primera línia”
PS> add-content info4.txt “segona línia”
PS> “tercera línia” >> info4.txt
- Per esborrar fitxers o carpetes, utilitzarem remove-item o l’alias del. En el cas de fitxers protegits amb “només lectura”, utilitzarem l’opció –force per esborrar-los.
- Crear un fitxer normal, després protegir-lo amb “read-only” i eliminar-lo:
PS> $f = New-item ex.txt –type file
PS> $f.isreadonly
false
PS> $f.isreadonly = $true
PS> del ex.txt –force
- Esborrar un directori que no està buit: PS> del directori –recurse
Accés al permisos des de PS
En NTFS, els permisos d’accés determinen quins usuaris poden accedir a fitxers i carpetes. Aquests permisos estan a les llistes de control d’accés (ACL), cada entrada d’aquesta llista s’anomena acces control entry (ACE). Get-Acl i Set-Acl són cmdlets del PS per modificar permisos. Icacls és una comanda tradicional que també permet modificar permisos, d’una forma més àgil que els cmdlets de PS; per consultar la seva ajuda: icacls /?Exemples
- Comprovar el propietari: PS> (get-acl c:\users).owner
- Llistar els permisos d’accés: PS> (get-acl c:\users).access
- Clonar permisos entre dues carpetes: PS> $acl=get-acl carpeta1 seguit de PS> set-acl carpeta2 $acl
Accés al sistema operatiu des de PS
PS permet accedir a qualsevol element del sistema, no només a usuaris i sistemes de fitxers si no també al propi sistema operatiu i fins i tot al maquinari.La classe d'objectes anomenada WMI (Windows Management Instrumentation) representa el sistema” en forma d'objectes, i ens proporciona accés a qualsevol
element intern: processador, BIOS, memòria, usuaris, serveis, etc...El seu nom normalment consisteix en el prefix “Win32” i el nom de l’element al qual accedeix. Per ex: Win32_BIOS descriu la BIOS.
Get-WmiObject ens permet llegir el valor de les propietats d’una classe WMI. Exemple:
PS C:\Users> Get-WmiObject Win32_Bios | format-listConsulta d’una propietat d’una instància d'un objecte del sistema:
SMBIOSBIOSVersion : VirtualBox
Manufacturer : innotek GmbH
Name : Default System BIOS
SerialNumber : 0
Version : VBOX - 1
PS> $bios=Get-WmiObject Win32_BiosPer poder modificar el valor d’una propietat d’una instància d’un WMI, s’han de cumplir 3 condicions:
PS> $bios | get-member
PS> $bios.version
- La propietat no ha de ser de només lectura
- S’ha de ser administrador, perquè el canvi afectarà a tots els usuaris
- En acabar, s’ha d’utilitzar la funció put() perquè els canvis tinguin efecte
Exemple: Canviem la descripció del processador
PS> $p=get-wmiobject win32_processor
PS> $p.description=“Model de la familia x64”
PS> $.put
Cap comentari:
Publica un comentari a l'entrada