Active Directory Nesneleri ve PowerShell İşlem Hattı
Bu makale bir süredir yazmayı düşündüğüm bir makale. İnsanlara PowerShell'in temel kavramlarını anladıktan sonra kullanımının kolay olduğunu ne kadar sık söylesem de durum her zaman böyle değildir. Bu, arkadaşım Gladys Kravitz'in bir süre önce dikkatimi çektiği bir sorun.
Onun gibi siz de muhtemelen ardışık düzen girişini kabul eden buna benzer bir PowerShell işlevi yazmışsınızdır.
Function Get-Foo {
[cmdletbinding()]
param(
[Parameter(Mandatory, ValueFromPipelinebyPropertyName)]
[string]$Name
)
Begin {}
Process {
Write-Host "working on $Name" -ForegroundColor Green
}
End {}
}Bu örnek işlev, gelen herhangi bir nesneye bakar ve Name özelliğini Name parametresine atar. Basit bir testle sonuçları görebilirsiniz.
Get-Service bits, winrm | Get-Foo
working on bits
working on winrm
Bu fonksiyon $Name parametresinin değerini görüntülemekten başka bir şey yapmıyor. İleriye doğru bir adım atalım.
Bilgisayar adı için ardışık düzen girdisi alan BITS hizmetini almaya yönelik basit bir işlevi burada bulabilirsiniz.
Function Get-Bits {
[cmdletbinding()]
param(
[Parameter(Mandatory, ValueFromPipelineByPropertyName)]
[alias("Name")]
[string]$Computername
)
Begin {}
Process {
Write-Host "$Computername" -ForegroundColor yellow
Get-service -Name bits -ComputerName $computername | Select-Object Machinename,Name,Status
}
End {}
}
Bu çoğunlukla beklendiği gibi çalışır. Bir parametre değeri belirtebilirim. Ayrıca boru hattından özellik adına göre de girdi alabilirim.
Gerçekte ne olduğunu görmenin zamanı gelmişti. Bu arada, Get-ADComputer komutunu Get-Member'a yönlendirirseniz, PowerShell size Name özelliğinin bir String olduğunu söyleyecektir.
Daha derine inmek için Trace-Command cmdlet'ine döndük. Kesinlikle yardım ve örnekleri okumak istersiniz. Bizim durumumuzda PowerShell'in parametre bağlamayla ne yaptığını görmemiz gerekiyordu.
Anlaşılacak çok şey var. Aşağı kaydırıp Get-Bits işlevine geldiğimde, PowerShell'in Bilgisayaradı için parametre bağlamayla ne yaptığını fark ettim.
PowerShell bir dize görmüyordu. Dönüştüremediği bir ADPropertyValueCollection görüyordu ve bu da hataya neden oluyordu.
Function Get-Bits {
#revised version
[cmdletbinding()]
param(
[Parameter(Mandatory, ValueFromPipelineByPropertyName)]
[alias("Name")]
[object]$Computername
)
Begin {}
Process {
write-Host "processing type $($computername.GetType().fullname)" -ForegroundColor yellow
[Microsoft.ActiveDirectory.Management.ADPropertyValueCollection]::new($Computername)
switch ($computername.GetType().fullname) {
"system.string" {$cn = $Computername}
"microsoft.activedirectory.management.adcomputer" {$cn = $computername.name}
"Microsoft.ActiveDirectory.Management.ADPropertyValueCollection" {$cn = [Microsoft.ActiveDirectory.Management.ADPropertyValueCollection]::new($computername).name }
default { $cn = $Computername.computername }
}
write-Host "working on $cn" -fore Green
# Get-service -Name bits -ComputerName $cn | Select-Object Machinename,Name,Status
}
End {}
}Bilgisayaradı için aldığım nesnenin türüne dikkat etmem gerekiyor. Bunun bir dizi olacağını varsayamıyorum. Teorimi doğrulamak istiyorum.
Gladys ve çoğu kişi AD Object özelliğinin String gibi basit bir şey olduğunu varsayıyordu. Ama açıkça öyle değil. Ayrıca testlerden Select-Object'in özelliği koleksiyondan aldığını ve Selected.Microsoft.ActiveDirectory.Management.ADComputer nesnesini oluşturmak için kullandığını da çıkarabiliyorum.
Artık bunu bildiğimize göre, bir Active Directory cmdlet'inden gelen ardışık düzen girişini daha iyi karşılamak için örnek fonksiyonumu revize edebilirim. Bu, parametre setlerinin kullanılmasını gerektirecektir.
Function Get-Bits {
#with parameter sets
[cmdletbinding(DefaultParameterSetName = "byString")]
param(
[Parameter(Mandatory, ValueFromPipelineByPropertyName, ValueFromPipeline, ParameterSetName = "byString")]
[alias("Name")]
[string]$Computername,
[Parameter(ValueFromPipeline, ParameterSetName = "byADComputer")]
[Microsoft.ActiveDirectory.Management.ADComputer]$Computer
)
Begin {
Write-Verbose "Starting $($myinvocation.mycommand)"
}
Process {
Write-Verbose "Using parameter set $($pscmdlet.ParameterSetName)"
if ($PSCmdlet.ParameterSetName -eq "byString") {
$cn = $Computername
}
else {
Write-Verbose "Getting the Name property"
$cn = $Computer.Name
}
Write-Verbose "Getting BITS service from $cn"
Try {
Get-Service -Name bits -ComputerName $cn -ErrorAction Stop |
Select-Object Machinename, Name, Status
}
Catch {
Write-Warning "Failed to get service status from $CN. $($_.exception.message)"
}
}
End {
Write-Verbose "Ending $($myinvocation.mycommand)"
}
}İşlevin bu sürümü, Bilgisayaradı için özellik adına veya diğer Ad'a göre işlem hattı girişini alacaktır. Veya bir ADComputer nesnesini işleyecektir. İşlem bloğunda Get-Service'e aktarılacak uygun bilgisayar adı değerini alabilirim. Bu sürüm bana beklediğim PowerShell deneyimini sunuyor.
En azından Gladys delirmediğini ve Active Directory komut dosyası oluşturma ihtiyaçlarına yönelik çözümler bulunduğunu biliyor. Trace-Command'ı denemenizi tavsiye ederim. Bir dahaki sefere bir sorunla karşılaştığınızda ve alnınızdaki morlukların sayısını azaltmak istediğinizde kullanışlı olabilir.
Her zamanki gibi yorum ve geribildirimlerinizi bekliyoruz.








