Capítulo 3: Detección de objetos, propiedades y métodos
Mi primer contacto con un equipo fue con un Commodore 64, pero el primero moderno que tuve fue un clon de IBM 286 a 12 MHz con 1 megabyte de memoria, una unidad de disco duro de 40 megabytes y una unidad de disquete de 5 1/4 pulgadas con un monitor CGA que ejecutaba Microsoft DOS 3.3.
Muchos profesionales de TI, como yo mismo, no son extraños a la línea de comandos, pero cuando aparece el asunto de objetos, propiedades y métodos, obtienen el ciervo en los faros miran y dicen: "No soy un desarrollador". ¿Adivina qué? Resulta que no hace falta ser desarrollador para usar PowerShell y hacerlo bien. Que nadie se deje confundir por la terminología. Puede que sea un poco confuso al principio, pero, después de obtener un poco de experiencia práctica, habrá momentos en los que todo de repente comienza a tener sentido. "¡Claro! A eso se refería el libro".
Es recomendable probar los ejemplos en el equipo para obtener un poco de esa experiencia práctica.
Requisitos
Algunos de los ejemplos que se muestran en este capítulo requieren el módulo Active Directory PowerShell. El módulo forma parte de las Herramientas de administración remota del servidor (RSAT) para Windows. Para la compilación 1809 (o posterior) de Windows, las herramientas de RSAT se instalan como una característica de Windows. La compatibilidad con Active Directory no está disponible en Windows Home.
- Para obtener información sobre cómo instalar las herramientas de RSAT, consulte Módulos de administración de Windows.
- Para versiones anteriores de Windows, consulte RSAT para Windows.
Get-Member
Get-Member
ayuda a detectar qué objetos, propiedades y métodos están disponibles para los comandos.
Cualquier comando que produzca una salida basada en objetos se puede canalizar a Get-Member
. Una propiedad es una característica de un elemento. Los permisos de conducir tienen una propiedad, "nombre", cuyos valores podrían ser Beatriz, Cristina, David o Pedro, por ejemplo. Un método es una acción que se puede realizar en un elemento. Siguiendo con el ejemplo de los permisos de conducir, uno de los métodos sería "revocar", ya que hay diferentes entidades gubernamentales que pueden revocarlos.
Propiedades
En el siguiente ejemplo, voy a recuperar información sobre el servicio de Hora de Windows que se ejecuta en mi equipo.
Get-Service -Name w32time
Status Name DisplayName
------ ---- -----------
Running w32time Windows Time
Status, Name y DisplayName son ejemplos de propiedades, tal como se muestra en el conjunto de resultados anterior. El valor de la propiedad Status es Running
, el valor de la propiedad Name es w32time
y el valor de DisplayName es Windows Time
.
Ahora canalizaré ese comando a Get-Member
:
Get-Service -Name w32time | Get-Member
TypeName: System.ServiceProcess.ServiceController
Name MemberType Definition
---- ---------- ----------
Name AliasProperty Name = ServiceName
RequiredServices AliasProperty RequiredServices = ServicesDependedOn
Disposed Event System.EventHandler Disposed(System.Object, Sy...
Close Method void Close()
Continue Method void Continue()
CreateObjRef Method System.Runtime.Remoting.ObjRef CreateObjRef(ty...
Dispose Method void Dispose(), void IDisposable.Dispose()
Equals Method bool Equals(System.Object obj)
ExecuteCommand Method void ExecuteCommand(int command)
GetHashCode Method int GetHashCode()
GetLifetimeService Method System.Object GetLifetimeService()
GetType Method type GetType()
InitializeLifetimeService Method System.Object InitializeLifetimeService()
Pause Method void Pause()
Refresh Method void Refresh()
Start Method void Start(), void Start(string[] args)
Stop Method void Stop()
WaitForStatus Method void WaitForStatus(System.ServiceProcess.Servi...
CanPauseAndContinue Property bool CanPauseAndContinue {get;}
CanShutdown Property bool CanShutdown {get;}
CanStop Property bool CanStop {get;}
Container Property System.ComponentModel.IContainer Container {get;}
DependentServices Property System.ServiceProcess.ServiceController[] Depe...
DisplayName Property string DisplayName {get;set;}
MachineName Property string MachineName {get;set;}
ServiceHandle Property System.Runtime.InteropServices.SafeHandle Serv...
ServiceName Property string ServiceName {get;set;}
ServicesDependedOn Property System.ServiceProcess.ServiceController[] Serv...
ServiceType Property System.ServiceProcess.ServiceType ServiceType ...
Site Property System.ComponentModel.ISite Site {get;set;}
StartType Property System.ServiceProcess.ServiceStartMode StartTy...
Status Property System.ServiceProcess.ServiceControllerStatus ...
ToString ScriptMethod System.Object ToString();
La primera línea de los resultados en el ejemplo anterior contiene información muy importante. TypeName indica qué tipo de objeto se devolvió. Se devolvió un objeto System.ServiceProcess. ServiceController en este ejemplo. Esto a menudo se abrevia como la parte de TypeName justo después del último punto; en este ejemplo sería ServiceController.
Una vez que se sepa el tipo de objeto que produce un comando, se puede utilizar esta información para buscar comandos que acepten ese tipo de objeto como entrada.
Get-Command -ParameterType ServiceController
CommandType Name Version Source
----------- ---- ------- ------
Cmdlet Get-Service 3.1.0.0 Microsof...
Cmdlet Restart-Service 3.1.0.0 Microsof...
Cmdlet Resume-Service 3.1.0.0 Microsof...
Cmdlet Set-Service 3.1.0.0 Microsof...
Cmdlet Start-Service 3.1.0.0 Microsof...
Cmdlet Stop-Service 3.1.0.0 Microsof...
Cmdlet Suspend-Service 3.1.0.0 Microsof...
Todos esos comandos tienen un parámetro que acepta un tipo de objeto ServiceController por canalización, entrada de parámetro o ambos.
Observe que hay más propiedades que las que se muestran de forma predeterminada. Aunque estas propiedades adicionales no se muestran de forma predeterminada, se pueden seleccionar de la canalización canalizando el comando al cmdlet Select-Object
y usando el parámetro Property. En el ejemplo siguiente se seleccionan todas las propiedades canalizando los resultados de Get-Service
a Select-Object
y especificando el carácter comodín *
como valor para el parámetro Property.
Get-Service -Name w32time | Select-Object -Property *
Name : w32time
RequiredServices : {}
CanPauseAndContinue : False
CanShutdown : True
CanStop : True
DisplayName : Windows Time
DependentServices : {}
MachineName : .
ServiceName : w32time
ServicesDependedOn : {}
ServiceHandle : SafeServiceHandle
Status : Running
ServiceType : Win32ShareProcess
StartType : Manual
Site :
Container :
También se pueden seleccionar propiedades específicas mediante una lista separada por comas para el valor del parámetro Property.
Get-Service -Name w32time | Select-Object -Property Status, Name, DisplayName, ServiceType
Status Name DisplayName ServiceType
------ ---- ----------- -----------
Running w32time Windows Time Win32ShareProcess
De forma predeterminada, se devuelven cuatro propiedades en una tabla y se devuelven cinco o más en una lista. Algunos comandos usan formatos personalizados para invalidar el número de propiedades que se muestran de forma predeterminada en una tabla.
Hay varios cmdlets Format-*
que se pueden usar para invalidar manualmente estos valores predeterminados. Los más comunes son Format-Table
y Format-List
, y ambos se tratarán en un próximo capítulo.
Se pueden usar caracteres comodín cuando se especifican los nombres de propiedad con Select-Object
.
Get-Service -Name w32time | Select-Object -Property Status, DisplayName, Can*
Status : Running
DisplayName : Windows Time
CanPauseAndContinue : False
CanShutdown : True
CanStop : True
En el ejemplo anterior, se usó Can*
como uno de los valores del parámetro Property para devolver todas las propiedades que comienzan con Can
. Entre ellas se incluyen CanPauseAndContinue, CanShutdown y CanStop.
Métodos
Los métodos son una acción que se puede realizar. Usando el parámetro MemberType se pueden restringir los resultados de Get-Member
para mostrar solo los métodos de Get-Service
.
Get-Service -Name w32time | Get-Member -MemberType Method
TypeName: System.ServiceProcess.ServiceController
Name MemberType Definition
---- ---------- ----------
Close Method void Close()
Continue Method void Continue()
CreateObjRef Method System.Runtime.Remoting.ObjRef CreateObjRef(type ...
Dispose Method void Dispose(), void IDisposable.Dispose()
Equals Method bool Equals(System.Object obj)
ExecuteCommand Method void ExecuteCommand(int command)
GetHashCode Method int GetHashCode()
GetLifetimeService Method System.Object GetLifetimeService()
GetType Method type GetType()
InitializeLifetimeService Method System.Object InitializeLifetimeService()
Pause Method void Pause()
Refresh Method void Refresh()
Start Method void Start(), void Start(string[] args)
Stop Method void Stop()
WaitForStatus Method void WaitForStatus(System.ServiceProcess.ServiceC...
Como se puede ver, hay muchos métodos. Se puede usar el método Stop para detener un servicio de Windows.
(Get-Service -Name w32time).Stop()
Ahora comprobemos si el servicio de Hora de Windows de verdad se ha detenido.
Get-Service -Name w32time
Status Name DisplayName
------ ---- -----------
Stopped w32time Windows Time
No suelo usar métodos, pero son algo que debe tenerse en cuenta. Habrá ocasiones en las que aparecerá un comando Get-*
sin un comando correspondiente para modificar dicho elemento.
A menudo, se puede usar un método para realizar una acción que lo modifique. El cmdlet Get-SqlAgentJob
del módulo SqlServer PowerShell es un buen ejemplo de esto. El módulo se instala como parte de SQL Server Management Studio (SSMS). No existe ningún cmdlet Set-*
correspondiente, pero se puede usar un método para completar la misma tarea.
Otro motivo para conocer los métodos es que muchos principiantes dan por hecho que no se pueden realizar cambios destructivos con comandos Get-*
. Pero estos comandos sí pueden producir problemas graves si se usan de forma incorrecta.
Una opción mejor es usar un cmdlet para realizar la acción si existe uno. Ahora vamos a iniciar el servicio de Hora de Windows, pero esta vez usaremos el cmdlet para iniciar los servicios.
Get-Service -Name w32time | Start-Service -PassThru
Status Name DisplayName
------ ---- -----------
Running w32time Windows Time
De forma predeterminada, Start-Service
no devuelve ningún resultado, del mismo modo que el método de inicio de Get-Service
.
Pero una de las ventajas de usar un cmdlet es que muchas veces el cmdlet ofrece funcionalidades adicionales que no están disponibles con un método. En el ejemplo anterior, se usó el parámetro PassThru. Esto provoca que un cmdlet produzca una salida, aunque normalmente no la produzca.
Hay que tener cuidado de no hacer suposiciones sobre la salida de un cmdlet. Todos sabemos lo que pasa cuando se presuponen las cosas. Ahora recuperaré información sobre el proceso de PowerShell que se ejecuta en mi equipo de entorno de laboratorio con Windows 10.
Get-Process -Name PowerShell
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName
------- ------ ----- ----- ------ -- -- -----------
922 48 107984 140552 2.84 9020 1 powershell
Acto seguido, canalizaré ese mismo comando a Get-Member:
Get-Process -Name PowerShell | Get-Member
TypeName: System.Diagnostics.Process
Name MemberType Definition
---- ---------- ----------
Handles AliasProperty Handles = Handlecount
Name AliasProperty Name = ProcessName
NPM AliasProperty NPM = NonpagedSystemMemorySize64
PM AliasProperty PM = PagedMemorySize64
SI AliasProperty SI = SessionId
VM AliasProperty VM = VirtualMemorySize64
WS AliasProperty WS = WorkingSet64
Disposed Event System.EventHandler Disposed(System.Object, ...
ErrorDataReceived Event System.Diagnostics.DataReceivedEventHandler ...
Exited Event System.EventHandler Exited(System.Object, Sy...
OutputDataReceived Event System.Diagnostics.DataReceivedEventHandler ...
BeginErrorReadLine Method void BeginErrorReadLine()
BeginOutputReadLine Method void BeginOutputReadLine()
CancelErrorRead Method void CancelErrorRead()
CancelOutputRead Method void CancelOutputRead()
Close Method void Close()
CloseMainWindow Method bool CloseMainWindow()
CreateObjRef Method System.Runtime.Remoting.ObjRef CreateObjRef(...
Dispose Method void Dispose(), void IDisposable.Dispose()
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetLifetimeService Method System.Object GetLifetimeService()
GetType Method type GetType()
InitializeLifetimeService Method System.Object InitializeLifetimeService()
Kill Method void Kill()
Refresh Method void Refresh()
Start Method bool Start()
ToString Method string ToString()
WaitForExit Method bool WaitForExit(int milliseconds), void Wai...
WaitForInputIdle Method bool WaitForInputIdle(int milliseconds), boo...
__NounName NoteProperty string __NounName=Process
BasePriority Property int BasePriority {get;}
Container Property System.ComponentModel.IContainer Container {...
EnableRaisingEvents Property bool EnableRaisingEvents {get;set;}
ExitCode Property int ExitCode {get;}
ExitTime Property datetime ExitTime {get;}
Handle Property System.IntPtr Handle {get;}
HandleCount Property int HandleCount {get;}
HasExited Property bool HasExited {get;}
Id Property int Id {get;}
MachineName Property string MachineName {get;}
MainModule Property System.Diagnostics.ProcessModule MainModule ...
MainWindowHandle Property System.IntPtr MainWindowHandle {get;}
MainWindowTitle Property string MainWindowTitle {get;}
MaxWorkingSet Property System.IntPtr MaxWorkingSet {get;set;}
MinWorkingSet Property System.IntPtr MinWorkingSet {get;set;}
Modules Property System.Diagnostics.ProcessModuleCollection M...
NonpagedSystemMemorySize Property int NonpagedSystemMemorySize {get;}
NonpagedSystemMemorySize64 Property long NonpagedSystemMemorySize64 {get;}
PagedMemorySize Property int PagedMemorySize {get;}
PagedMemorySize64 Property long PagedMemorySize64 {get;}
PagedSystemMemorySize Property int PagedSystemMemorySize {get;}
PagedSystemMemorySize64 Property long PagedSystemMemorySize64 {get;}
PeakPagedMemorySize Property int PeakPagedMemorySize {get;}
PeakPagedMemorySize64 Property long PeakPagedMemorySize64 {get;}
PeakVirtualMemorySize Property int PeakVirtualMemorySize {get;}
PeakVirtualMemorySize64 Property long PeakVirtualMemorySize64 {get;}
PeakWorkingSet Property int PeakWorkingSet {get;}
PeakWorkingSet64 Property long PeakWorkingSet64 {get;}
PriorityBoostEnabled Property bool PriorityBoostEnabled {get;set;}
PriorityClass Property System.Diagnostics.ProcessPriorityClass Prio...
PrivateMemorySize Property int PrivateMemorySize {get;}
PrivateMemorySize64 Property long PrivateMemorySize64 {get;}
PrivilegedProcessorTime Property timespan PrivilegedProcessorTime {get;}
ProcessName Property string ProcessName {get;}
ProcessorAffinity Property System.IntPtr ProcessorAffinity {get;set;}
Responding Property bool Responding {get;}
SafeHandle Property Microsoft.Win32.SafeHandles.SafeProcessHandl...
SessionId Property int SessionId {get;}
Site Property System.ComponentModel.ISite Site {get;set;}
StandardError Property System.IO.StreamReader StandardError {get;}
StandardInput Property System.IO.StreamWriter StandardInput {get;}
StandardOutput Property System.IO.StreamReader StandardOutput {get;}
StartInfo Property System.Diagnostics.ProcessStartInfo StartInf...
StartTime Property datetime StartTime {get;}
SynchronizingObject Property System.ComponentModel.ISynchronizeInvoke Syn...
Threads Property System.Diagnostics.ProcessThreadCollection T...
TotalProcessorTime Property timespan TotalProcessorTime {get;}
UserProcessorTime Property timespan UserProcessorTime {get;}
VirtualMemorySize Property int VirtualMemorySize {get;}
VirtualMemorySize64 Property long VirtualMemorySize64 {get;}
WorkingSet Property int WorkingSet {get;}
WorkingSet64 Property long WorkingSet64 {get;}
PSConfiguration PropertySet PSConfiguration {Name, Id, PriorityClass, Fi...
PSResources PropertySet PSResources {Name, Id, Handlecount, WorkingS...
Company ScriptProperty System.Object Company {get=$this.Mainmodule....
CPU ScriptProperty System.Object CPU {get=$this.TotalProcessorT...
Description ScriptProperty System.Object Description {get=$this.Mainmod...
FileVersion ScriptProperty System.Object FileVersion {get=$this.Mainmod...
Path ScriptProperty System.Object Path {get=$this.Mainmodule.Fil...
Product ScriptProperty System.Object Product {get=$this.Mainmodule....
ProductVersion ScriptProperty System.Object ProductVersion {get=$this.Main...
Observe que hay más propiedades enumeradas que las que se muestran de forma predeterminada. Varias de las propiedades predeterminadas que se muestran no aparecen como propiedades al consultar los resultados de Get-Member
. Esto se debe a que muchos de los valores mostrados, como NPM(K)
, PM(K)
, WS(K)
y CPU(s)
, son propiedades calculadas. Para determinar los nombres reales de las propiedades, el comando se debe canalizar a Get-Member
.
Si un comando no produce una salida, no se puede canalizar a Get-Member
. Dado que Start-Service
no produce ninguna salida de forma predeterminada, genera un error cuando se intenta canalizar a Get-Member
.
Start-Service -Name w32time | Get-Member
Get-Member : You must specify an object for the Get-Member cmdlet.
At line:1 char:31
+ Start-Service -Name w32time | Get-Member
+
+ CategoryInfo : CloseError: (:) [Get-Member], InvalidOperationException
+ FullyQualifiedErrorId : NoObjectInGetMember,Microsoft.PowerShell.Commands.GetMembe
rCommand
Se puede especificar el parámetro PassThru con el cmdlet Start-Service
para hacer que produzca la salida, la cual se canalizaría a Get-Member
sin errores.
Start-Service -Name w32time -PassThru | Get-Member
TypeName: System.ServiceProcess.ServiceController
Name MemberType Definition
---- ---------- ----------
Name AliasProperty Name = ServiceName
RequiredServices AliasProperty RequiredServices = ServicesDependedOn
Disposed Event System.EventHandler Disposed(System.Object, Sy...
Close Method void Close()
Continue Method void Continue()
CreateObjRef Method System.Runtime.Remoting.ObjRef CreateObjRef(ty...
Dispose Method void Dispose(), void IDisposable.Dispose()
Equals Method bool Equals(System.Object obj)
ExecuteCommand Method void ExecuteCommand(int command)
GetHashCode Method int GetHashCode()
GetLifetimeService Method System.Object GetLifetimeService()
GetType Method type GetType()
InitializeLifetimeService Method System.Object InitializeLifetimeService()
Pause Method void Pause()
Refresh Method void Refresh()
Start Method void Start(), void Start(string[] args)
Stop Method void Stop()
WaitForStatus Method void WaitForStatus(System.ServiceProcess.Servi...
CanPauseAndContinue Property bool CanPauseAndContinue {get;}
CanShutdown Property bool CanShutdown {get;}
CanStop Property bool CanStop {get;}
Container Property System.ComponentModel.IContainer Container {get;}
DependentServices Property System.ServiceProcess.ServiceController[] Depe...
DisplayName Property string DisplayName {get;set;}
MachineName Property string MachineName {get;set;}
ServiceHandle Property System.Runtime.InteropServices.SafeHandle Serv...
ServiceName Property string ServiceName {get;set;}
ServicesDependedOn Property System.ServiceProcess.ServiceController[] Serv...
ServiceType Property System.ServiceProcess.ServiceType ServiceType ...
Site Property System.ComponentModel.ISite Site {get;set;}
StartType Property System.ServiceProcess.ServiceStartMode StartTy...
Status Property System.ServiceProcess.ServiceControllerStatus ...
ToString ScriptMethod System.Object ToString();
Para que se canalice a Get-Member
, un comando debe producir una salida basada en objetos.
Get-Service -Name w32time | Out-Host | Get-Member
Status Name DisplayName
------ ---- -----------
Running w32time Windows Time
Get-Member : You must specify an object for the Get-Member cmdlet.
At line:1 char:40
+ Get-Service -Name w32time | Out-Host | Get-Member
+
+ CategoryInfo : CloseError: (:) [Get-Member], InvalidOperationException
+ FullyQualifiedErrorId : NoObjectInGetMember,Microsoft.PowerShell.Commands.GetMemberCommand
Out-Host
escribe directamente en el host de PowerShell, pero no produce una salida basada en objetos para la canalización. Por lo tanto, no se puede canalizar a Get-Member
.
Active Directory
Nota:
Las Herramientas de administración remota del servidor que aparecen en la sección de requisitos de este capítulo son necesarias para completar esta sección. Además, tal y como se mencionó en la introducción de este libro, es necesario que el equipo de entorno de laboratorio con Windows 10 sea miembro del dominio de entorno de laboratorio.
Ahora vamos a usar Get-Command
con el parámetro Module para determinar qué comandos se agregaron como parte del módulo ActiveDirectory PowerShell cuando se instalaron las herramientas de administración remota del servidor.
Get-Command -Module ActiveDirectory
CommandType Name Version Source
----------- ---- ------- ------
Cmdlet Add-ADCentralAccessPolicyMember 1.0.0.0 ActiveDi...
Cmdlet Add-ADComputerServiceAccount 1.0.0.0 ActiveDi...
Cmdlet Add-ADDomainControllerPasswordReplicationPolicy 1.0.0.0 ActiveDi...
Cmdlet Add-ADFineGrainedPasswordPolicySubject 1.0.0.0 ActiveDi...
Cmdlet Add-ADGroupMember 1.0.0.0 ActiveDi...
Cmdlet Add-ADPrincipalGroupMembership 1.0.0.0 ActiveDi...
Cmdlet Add-ADResourcePropertyListMember 1.0.0.0 ActiveDi...
Cmdlet Clear-ADAccountExpiration 1.0.0.0 ActiveDi...
Cmdlet Clear-ADClaimTransformLink 1.0.0.0 ActiveDi...
Cmdlet Disable-ADAccount 1.0.0.0 ActiveDi...
...
Se ha agregado un total de 147 comandos como parte del módulo ActiveDirectory PowerShell. Algunos comandos de estos comandos solo devuelven una parte de las propiedades disponibles de forma predeterminada.
¿No ha observado algo distinto en relación con los nombres de los comandos en este módulo? La parte del nombre de los comandos tiene un prefijo AD. Es habitual ver esto en los comandos de la mayoría de los módulos. El prefijo está diseñado para evitar conflictos de nomenclatura.
Get-ADUser -Identity mike | Get-Member
TypeName: Microsoft.ActiveDirectory.Management.ADUser
Name MemberType Definition
---- ---------- ----------
Contains Method bool Contains(string propertyName)
Equals Method bool Equals(System.Object obj)
GetEnumerator Method System.Collections.IDictionaryEnumerator GetEn...
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
Item ParameterizedProperty Microsoft.ActiveDirectory.Management.ADPropert...
DistinguishedName Property System.String DistinguishedName {get;set;}
Enabled Property System.Boolean Enabled {get;set;}
GivenName Property System.String GivenName {get;set;}
Name Property System.String Name {get;}
ObjectClass Property System.String ObjectClass {get;set;}
ObjectGUID Property System.Nullable`1[[System.Guid, mscorlib, Vers...
SamAccountName Property System.String SamAccountName {get;set;}
SID Property System.Security.Principal.SecurityIdentifier S...
Surname Property System.String Surname {get;set;}
UserPrincipalName Property System.String UserPrincipalName {get;set;}
Aunque apenas esté familiarizado con Active Directory, podría entender que una cuenta de usuario tiene más propiedades que las que se muestran en este ejemplo.
El cmdlet Get-ADUser
tiene un parámetro Properties que se usa para especificar las propiedades (no predeterminadas) adicionales que quiera devolver. Todas se devuelven al especificar el carácter comodín *
.
Get-ADUser -Identity mike -Properties * | Get-Member
TypeName: Microsoft.ActiveDirectory.Management.ADUser
Name MemberType Definition
---- ---------- ----------
Contains Method bool Contains(string proper...
Equals Method bool Equals(System.Object obj)
GetEnumerator Method System.Collections.IDiction...
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
Item ParameterizedProperty Microsoft.ActiveDirectory.M...
AccountExpirationDate Property System.DateTime AccountExpi...
accountExpires Property System.Int64 accountExpires...
AccountLockoutTime Property System.DateTime AccountLock...
AccountNotDelegated Property System.Boolean AccountNotDe...
AllowReversiblePasswordEncryption Property System.Boolean AllowReversi...
AuthenticationPolicy Property Microsoft.ActiveDirectory.M...
AuthenticationPolicySilo Property Microsoft.ActiveDirectory.M...
BadLogonCount Property System.Int32 BadLogonCount ...
badPasswordTime Property System.Int64 badPasswordTim...
badPwdCount Property System.Int32 badPwdCount {g...
CannotChangePassword Property System.Boolean CannotChange...
CanonicalName Property System.String CanonicalName...
Certificates Property Microsoft.ActiveDirectory.M...
City Property System.String City {get;set;}
CN Property System.String CN {get;}
codePage Property System.Int32 codePage {get;...
Company Property System.String Company {get;...
CompoundIdentitySupported Property Microsoft.ActiveDirectory.M...
Country Property System.String Country {get;...
countryCode Property System.Int32 countryCode {g...
Created Property System.DateTime Created {get;}
createTimeStamp Property System.DateTime createTimeS...
Deleted Property System.Boolean Deleted {get;}
Department Property System.String Department {g...
Description Property System.String Description {...
DisplayName Property System.String DisplayName {...
DistinguishedName Property System.String Distinguished...
Division Property System.String Division {get...
DoesNotRequirePreAuth Property System.Boolean DoesNotRequi...
dSCorePropagationData Property Microsoft.ActiveDirectory.M...
EmailAddress Property System.String EmailAddress ...
EmployeeID Property System.String EmployeeID {g...
EmployeeNumber Property System.String EmployeeNumbe...
Enabled Property System.Boolean Enabled {get...
Fax Property System.String Fax {get;set;}
GivenName Property System.String GivenName {ge...
HomeDirectory Property System.String HomeDirectory...
HomedirRequired Property System.Boolean HomedirRequi...
HomeDrive Property System.String HomeDrive {ge...
HomePage Property System.String HomePage {get...
HomePhone Property System.String HomePhone {ge...
Initials Property System.String Initials {get...
instanceType Property System.Int32 instanceType {...
isDeleted Property System.Boolean isDeleted {g...
KerberosEncryptionType Property Microsoft.ActiveDirectory.M...
LastBadPasswordAttempt Property System.DateTime LastBadPass...
LastKnownParent Property System.String LastKnownPare...
lastLogoff Property System.Int64 lastLogoff {ge...
lastLogon Property System.Int64 lastLogon {get...
LastLogonDate Property System.DateTime LastLogonDa...
lastLogonTimestamp Property System.Int64 lastLogonTimes...
LockedOut Property System.Boolean LockedOut {g...
logonCount Property System.Int32 logonCount {ge...
LogonWorkstations Property System.String LogonWorkstat...
Manager Property System.String Manager {get;...
MemberOf Property Microsoft.ActiveDirectory.M...
MNSLogonAccount Property System.Boolean MNSLogonAcco...
MobilePhone Property System.String MobilePhone {...
Modified Property System.DateTime Modified {g...
modifyTimeStamp Property System.DateTime modifyTimeS...
msDS-User-Account-Control-Computed Property System.Int32 msDS-User-Acco...
Name Property System.String Name {get;}
nTSecurityDescriptor Property System.DirectoryServices.Ac...
ObjectCategory Property System.String ObjectCategor...
ObjectClass Property System.String ObjectClass {...
ObjectGUID Property System.Nullable`1[[System.G...
objectSid Property System.Security.Principal.S...
Office Property System.String Office {get;s...
OfficePhone Property System.String OfficePhone {...
Organization Property System.String Organization ...
OtherName Property System.String OtherName {ge...
PasswordExpired Property System.Boolean PasswordExpi...
PasswordLastSet Property System.DateTime PasswordLas...
PasswordNeverExpires Property System.Boolean PasswordNeve...
PasswordNotRequired Property System.Boolean PasswordNotR...
POBox Property System.String POBox {get;set;}
PostalCode Property System.String PostalCode {g...
PrimaryGroup Property System.String PrimaryGroup ...
primaryGroupID Property System.Int32 primaryGroupID...
PrincipalsAllowedToDelegateToAccount Property Microsoft.ActiveDirectory.M...
ProfilePath Property System.String ProfilePath {...
ProtectedFromAccidentalDeletion Property System.Boolean ProtectedFro...
pwdAnswer Property System.String pwdAnswer {ge...
pwdLastSet Property System.Int64 pwdLastSet {ge...
pwdQuestion Property System.String pwdQuestion {...
SamAccountName Property System.String SamAccountNam...
sAMAccountType Property System.Int32 sAMAccountType...
ScriptPath Property System.String ScriptPath {g...
sDRightsEffective Property System.Int32 sDRightsEffect...
ServicePrincipalNames Property Microsoft.ActiveDirectory.M...
SID Property System.Security.Principal.S...
SIDHistory Property Microsoft.ActiveDirectory.M...
SmartcardLogonRequired Property System.Boolean SmartcardLog...
sn Property System.String sn {get;set;}
State Property System.String State {get;set;}
StreetAddress Property System.String StreetAddress...
Surname Property System.String Surname {get;...
Title Property System.String Title {get;set;}
TrustedForDelegation Property System.Boolean TrustedForDe...
TrustedToAuthForDelegation Property System.Boolean TrustedToAut...
UseDESKeyOnly Property System.Boolean UseDESKeyOnl...
userAccountControl Property System.Int32 userAccountCon...
userCertificate Property Microsoft.ActiveDirectory.M...
UserPrincipalName Property System.String UserPrincipal...
uSNChanged Property System.Int64 uSNChanged {get;}
uSNCreated Property System.Int64 uSNCreated {get;}
whenChanged Property System.DateTime whenChanged...
whenCreated Property System.DateTime whenCreated...
Mucho mejor.
¿Cuál podría ser un motivo por el que las propiedades de una cuenta de usuario de Active Directory podrían estar tan limitadas de forma predeterminada? Imaginemos qué pasaría si se devolviera cada propiedad para cada cuenta de usuario en el entorno de Active Directory de producción. Pensemos en la degradación del rendimiento que podría provocar, y no solo en los controladores de dominio, sino también en la red. No está claro que de verdad se necesiten todas las propiedades. Devolver todas las propiedades a una cuenta de usuario única es perfectamente aceptable cuando se intenta determinar qué propiedades existen.
No es raro ejecutar un comando muchas veces al crear un prototipo. Si va a realizar una consulta enorme, es preferible realizarla una vez y almacenar los resultados en una variable. Hecho esto, se trabajaría con el contenido de la variable, en lugar de usar repetidamente una consulta costosa.
$Users = Get-ADUser -Identity mike -Properties *
Es mejor usar el contenido de la variable $Users
, en lugar de ejecutar el comando anterior varias veces.
Tenga en cuenta que el contenido de la variable no se actualizará cuando se realicen cambios en el usuario en Active Directory.
Puede canalizarse la variable $Users
a Get-Member
para detectar las propiedades disponibles.
$Users | Get-Member
Después, seleccione las propiedades individuales mediante la canalización de $Users
a Select-Object
, sin tener que consultar Active Directory más de una vez.
$Users | Select-Object -Property Name, LastLogonDate, LastBadPasswordAttempt
Si va a consultar Active Directory más de una vez, puede usar el parámetro Properties para especificar las propiedades no predeterminadas que quiera.
Get-ADUser -Identity mike -Properties LastLogonDate, LastBadPasswordAttempt
DistinguishedName : CN=Mike F. Robbins,OU=Sales,DC=mikefrobbins,DC=com
Enabled : True
GivenName : Mike
LastBadPasswordAttempt : 2/4/2017 10:46:15 AM
LastLogonDate : 2/18/2017 12:45:14 AM
Name : Mike F. Robbins
ObjectClass : user
ObjectGUID : a82a8c58-1332-4a57-a6e2-68e0c750ea56
SamAccountName : mike
SID : S-1-5-21-2989741381-570885089-3319121794-1108
Surname : Robbins
UserPrincipalName : miker@mikefrobbins.com
Resumen
En este capítulo hemos aprendido cómo determinar el tipo de objeto que puede producir un comando, cómo determinar qué propiedades y métodos están disponibles para un comando y cómo trabajar con comandos que limitan las propiedades que se devuelven de forma predeterminada.
Revisar
- ¿Qué tipo de objeto produce el cmdlet
Get-Process
? - ¿Cómo se determinan las propiedades disponibles para un comando?
- Si existe un comando para obtener algo, pero no para establecer lo mismo, ¿qué se debe comprobar?
- ¿Qué puede hacerse para que determinados comandos que no producen una salida de forma predeterminada puedan producir una salida?
- Si se va a trabajar con los resultados de un comando que produce una gran cantidad de salidas, ¿qué se podría hacer?
Lecturas recomendadas
Comentarios
https://aka.ms/ContentUserFeedback.
Próximamente: A lo largo de 2024 iremos eliminando gradualmente GitHub Issues como mecanismo de comentarios sobre el contenido y lo sustituiremos por un nuevo sistema de comentarios. Para más información, vea:Enviar y ver comentarios de