PowerShell işlevlerine Kimlik Bilgisi desteği ekleme
Not
Bu makalenin orijinal versiyonu @joshduffney tarafından yazılan blogda yayınlandı. Bu makale bu siteye eklenmek üzere düzenlenmiştir. PowerShell ekibi bu içeriği bizimle paylaştığı için Josh'a teşekkür ediyor. Lütfen duffney.io adresindeki bloguna göz atın.
Bu makalede, PowerShell işlevlerine kimlik bilgisi parametrelerinin nasıl ekleneceği ve neden bunu isteyeceğiniz gösterilmektedir. Kimlik bilgisi parametresi, işlevi veya cmdlet'i farklı bir kullanıcı olarak çalıştırmanıza olanak tanır. En yaygın kullanım, işlevi veya cmdlet'i yükseltilmiş kullanıcı hesabı olarak çalıştırmaktır.
Örneğin, Yeni-ADUser cmdlet'i, bir alanda hesap oluşturmak için alan yöneticisi kimlik bilgilerini sağlayabileceğiniz bir Kimlik Bilgisi parametresine sahiptir. PowerShell oturumunu çalıştıran normal hesabınızın halihazırda bu erişime sahip olmadığını varsayarsak.
Kimlik bilgisi nesnesi oluşturma
PSCredential nesnesi, kullanıcı adı ve parola gibi bir dizi güvenlik kimlik bilgisini temsil eder. Nesne, söz konusu kimlik bilgisi nesnesinde kullanıcı hesabı olarak çalışan bir işleve parametre olarak aktarılabilir. Kimlik bilgisi nesnesi oluşturmanın birkaç yolu vardır. Kimlik bilgisi nesnesi oluşturmanın ilk yolu PowerShell cmdlet'ini Get-Credential kullanmaktır. Parametresiz çalıştırdığınızda sizden kullanıcı adı ve şifre istiyor. Veya cmdlet'i bazı isteğe bağlı parametrelerle çağırabilirsiniz.
Alan adını ve kullanıcı adını önceden belirtmek için Kimlik Bilgisi veya KullanıcıAdı parametrelerini kullanabilirsiniz. KullanıcıAdı parametresini kullandığınızda ayrıca bir Mesaj değeri de sağlamanız gerekir. Aşağıdaki kod cmdlet'in kullanımını gösterir. Kimlik bilgisini birden çok kez kullanabilmeniz için kimlik bilgisi nesnesini bir değişkende de saklayabilirsiniz. Aşağıdaki örnekte, kimlik bilgisi nesnesi $Cred değişkeninde saklanmaktadır.
$Cred = Get-Credential
$Cred = Get-Credential -Credential domain\user
$Cred = Get-Credential -UserName domain\user -Message 'Enter Password'
Bazen önceki örnekte gösterilen kimlik bilgisi nesnelerini oluşturmanın etkileşimli yöntemini kullanamazsınız. Çoğu otomasyon aracı etkileşimli olmayan bir yöntem gerektirir. Kullanıcı etkileşimi olmadan bir kimlik bilgisi oluşturmak için parolayı içeren güvenli bir dize oluşturun. Daha sonra güvenli dizeyi ve kullanıcı adını System.Management.Automation.PSCredential() yöntemine iletin.
Parolayı içeren güvenli bir dize oluşturmak için aşağıdaki komutu kullanın:
ConvertTo-SecureString "MyPlainTextPassword" -AsPlainText -Force
Hem AsPlainText hem de Force parametreleri gereklidir. Bu parametreler olmadan, düz metni güvenli bir dizeye geçirmemeniz gerektiğini bildiren bir uyarı mesajı alırsınız. Düz metin parolası çeşitli günlüklere kaydedildiğinden PowerShell bu uyarıyı döndürür. Güvenli bir dize oluşturduktan sonra, kimlik bilgisi nesnesini oluşturmak için bunu PSCredential() yöntemine aktarmanız gerekir. Aşağıdaki örnekte, $password değişkeni, kimlik bilgisi nesnesini içeren güvenli dizeyi $Cred içerir.
$password = ConvertTo-SecureString "MyPlainTextPassword" -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential ("username", $password)
Artık kimlik bilgisi nesnelerini nasıl oluşturacağınızı bildiğinize göre PowerShell işlevlerinize kimlik bilgisi parametreleri ekleyebilirsiniz.
Kimlik Bilgisi Parametresi Ekleme
Tıpkı diğer parametreler gibi, onu da işlevinizin param bloğuna ekleyerek başlarsınız. Mevcut PowerShell cmdlet'leri bunu kullandığından $Credential parametresini adlandırmanız önerilir. Parametrenin türü [System.Management.Automation.PSCredential] olmalıdır.
Aşağıdaki örnek, Get-Something adlı bir işlevin parametre bloğunu gösterir. İki parametresi vardır: $Name ve $Credential.
function Get-Something {
param(
$Name,
[System.Management.Automation.PSCredential]$Credential
)
Bu örnekteki kod, çalışan bir kimlik bilgisi parametresine sahip olmak için yeterlidir, ancak onu daha sağlam hale getirmek için ekleyebileceğiniz birkaç şey vardır.
Değerin Kimlik Bilgisi'ne aktarıldığını kontrol etmek için
[ValidateNotNull()]doğrulama özelliğini ekleyin. Parametre değeri null ise bu öznitelik, işlevin geçersiz kimlik bilgileriyle yürütülmesini engeller.[System.Management.Automation.Credential()]ekleyin. Bu, kullanıcı adını bir dize olarak girmenize ve etkileşimli bir parola istemine sahip olmanıza olanak tanır.-
$Credentialparametresi için varsayılan değeri[System.Management.Automation.PSCredential]::Emptyolarak ayarlayın. İşleviniz bu$Credentialnesnesini mevcut PowerShell cmdlet'lerine aktarıyor olabilirsiniz. İşlevinizin içinde çağrılan cmdlet'e boş bir değer sağlamak hataya neden olur. Boş bir kimlik bilgisi nesnesi sağlamak bu hatayı önler.
Yararlı ipucu
Kimlik bilgisi parametresini kabul eden bazı cmdlet'ler, olması gerektiği gibi [System.Management.Automation.PSCredential]::Empty öğesini desteklemez. Geçici bir çözüm için Eski Cmdlet'lerle Başa Çıkma bölümüne bakın.
Kimlik bilgisi parametrelerini kullanma
Aşağıdaki örnek, kimlik bilgisi parametrelerinin nasıl kullanılacağını gösterir. Bu örnekte The Pester Book'tan çıkan Set-RemoteRegistryValue adlı bir işlev gösterilmektedir. Bu işlev, önceki bölümde açıklanan teknikleri kullanarak kimlik bilgisi parametresini tanımlar. İşlev, işlev tarafından oluşturulan $Credential değişkenini kullanarak Invoke-Command'ı çağırır. Bu, Invoke-Command'ı çalıştıran kullanıcıyı değiştirmenize olanak tanır. $Credential'ın varsayılan değeri boş bir kimlik bilgisi olduğundan, işlev, kimlik bilgileri sağlanmadan çalışabilir.
function Set-RemoteRegistryValue {
param(
$ComputerName,
$Path,
$Name,
$Value,
[ValidateNotNull()]
[System.Management.Automation.PSCredential]
[System.Management.Automation.Credential()]
$Credential = [System.Management.Automation.PSCredential]::Empty
)
$null = Invoke-Command -ComputerName $ComputerName -ScriptBlock {
Set-ItemProperty -Path $using:Path -Name $using:Name -Value $using:Value
} -Credential $Credential
}
Aşağıdaki bölümlerde Set-RemoteRegistryValue'ya kimlik bilgileri sağlamanın farklı yöntemleri gösterilmektedir.
Kimlik bilgilerini isteme
Çalışma zamanında parantez içinde () içinde Get-Credential kullanılması, önce Get-credential'ın çalıştırılmasına neden olur. Bir kullanıcı adı ve şifre girmeniz istenir. Kullanıcı adını ve etki alanını önceden doldurmak için Kimlik bilgisi al'ın Kimlik Bilgisi veya KullanıcıAdı parametrelerini kullanabilirsiniz. Aşağıdaki örnek, parametreleri Set-RemoteRegistryValue işlevine geçirmek için splatting adı verilen bir teknik kullanır. Splatting hakkında daha fazla bilgi için about_Splatting makalesine göz atın.
$remoteKeyParams = @{
ComputerName = $env:COMPUTERNAME
Path = 'HKLM:\SOFTWARE\Microsoft\WebManagement\Server'
Name = 'EnableRemoteManagement'
Value = '1'
}
Set-RemoteRegistryValue @remoteKeyParams -Credential (Get-Credential)
(Get-Credential)'ı kullanmak hantal görünüyor. Normalde, Kimlik Bilgisi parametresini yalnızca bir kullanıcı adıyla kullandığınızda cmdlet otomatik olarak şifre ister. [System.Management.Automation.Credential()] özelliği bu davranışı etkinleştirir.
$remoteKeyParams = @{
ComputerName = $env:COMPUTERNAME
Path = 'HKLM:\SOFTWARE\Microsoft\WebManagement\Server'
Name = 'EnableRemoteManagement'
Value = '1'
}
Set-RemoteRegistryValue @remoteKeyParams -Credential duffney
Not
Gösterilen kayıt defteri değerini ayarlamak için bu örneklerde Windows'un Web Sunucusu özelliklerinin yüklü olduğu varsayılmaktadır. Gerekirse Install-WindowsFeature Web-Server ve Install-WindowsFeature web-mgmt-tools'u çalıştırın.
Bir değişkende kimlik bilgileri sağlayın
Ayrıca bir kimlik bilgisi değişkenini önceden doldurabilir ve bunu Set-RemoteRegistryValue işlevinin Credential parametresine aktarabilirsiniz. Bu yöntemi Jenkins, TeamCity ve Octopus Deploy gibi Sürekli Entegrasyon/Sürekli Dağıtım (CI/CD) araçlarıyla kullanın. Jenkins kullanımına ilişkin bir örnek için Hodge'un Windows'ta Jenkins ve PowerShell ile Otomatikleştirme - Bölüm 2 adlı blog gönderisine göz atın.
Bu örnek, kimlik bilgisi nesnesini ve parolayı iletecek güvenli bir dize oluşturmak için .NET yöntemini kullanır.
$password = ConvertTo-SecureString "P@ssw0rd" -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential ("duffney", $password)
$remoteKeyParams = @{
ComputerName = $env:COMPUTERNAME
Path = 'HKLM:\SOFTWARE\Microsoft\WebManagement\Server'
Name = 'EnableRemoteManagement'
Value = '1'
}
Set-RemoteRegistryValue @remoteKeyParams -Credential $Cred
Bu örnekte, güvenli dize, açık metin parolası kullanılarak oluşturulur. Daha önce bahsedilen CI/CD'lerin tümü, çalışma zamanında bu parolayı sağlamaya yönelik güvenli bir yönteme sahiptir. Bu araçları kullanırken düz metin parolasını, kullandığınız CI/CD aracında tanımlanan değişkenle değiştirin.
Kimlik bilgileri olmadan çalıştır
$Credential varsayılan olarak boş bir kimlik bilgisi nesnesine ayarlandığından, bu örnekte gösterildiği gibi, komutu kimlik bilgileri olmadan çalıştırabilirsiniz:
$remoteKeyParams = @{
ComputerName = $env:COMPUTERNAME
Path = 'HKLM:\SOFTWARE\Microsoft\WebManagement\Server'
Name = 'EnableRemoteManagement'
Value = '1'
}
Set-RemoteRegistryValue @remoteKeyParams
Eski cmdlet'lerle ilgilenme
Tüm cmdlet'ler kimlik bilgisi nesnelerini desteklemez veya boş kimlik bilgilerine izin vermez. Bunun yerine cmdlet, kullanıcı adı ve parola parametrelerini dize olarak ister. Bu sınırlamayı aşmanın birkaç yolu vardır.
Boş kimlik bilgilerini işlemek için if-else kullanma
Bu senaryoda çalıştırmak istediğiniz cmdlet boş bir kimlik bilgisi nesnesini kabul etmez. Bu örnek, Credential parametresini yalnızca boş değilse Invoke-Command'a ekler. Aksi takdirde, Kimlik Bilgisi parametresi olmadan Invoke-Command'ı çalıştırır.
function Set-RemoteRegistryValue {
param(
$ComputerName,
$Path,
$Name,
$Value,
[ValidateNotNull()]
[System.Management.Automation.PSCredential]
[System.Management.Automation.Credential()]
$Credential = [System.Management.Automation.PSCredential]::Empty
)
if($Credential -ne [System.Management.Automation.PSCredential]::Empty) {
Invoke-Command -ComputerName:$ComputerName -Credential:$Credential {
Set-ItemProperty -Path $using:Path -Name $using:Name -Value $using:Value
}
} else {
Invoke-Command -ComputerName:$ComputerName {
Set-ItemProperty -Path $using:Path -Name $using:Name -Value $using:Value
}
}
}
Boş kimlik bilgilerini işlemek için sıçramayı kullanma
Bu örnek, eski cmdlet'i çağırmak için parametre sıçramasını kullanır. $Credential nesnesi, sıçratma için karma tablosuna koşullu olarak eklenir ve Invoke-Command komut dosyası bloğunun tekrarlanması ihtiyacını ortadan kaldırır. İşlevlerin içine sıçrama hakkında daha fazla bilgi edinmek için Gelişmiş İşlevlerin İçindeki Splatting Parametreleri blog gönderisine bakın.
function Set-RemoteRegistryValue {
param(
$ComputerName,
$Path,
$Name,
$Value,
[ValidateNotNull()]
[System.Management.Automation.PSCredential]
[System.Management.Automation.Credential()]
$Credential = [System.Management.Automation.PSCredential]::Empty
)
$Splat = @{
ComputerName = $ComputerName
}
if ($Credential -ne [System.Management.Automation.PSCredential]::Empty) {
$Splat['Credential'] = $Credential
}
$null = Invoke-Command -ScriptBlock {
Set-ItemProperty -Path $using:Path -Name $using:Name -Value $using:Value
} @splat
}
Dize parolalarıyla çalışma
Invoke-Sqlcmd cmdlet'i, bir dizeyi parola olarak kabul eden bir cmdlet örneğidir. Invoke-Sqlcmd basit SQL ekleme, güncelleme ve silme ifadelerini çalıştırmanıza olanak tanır. Invoke-Sqlcmd, daha güvenli bir kimlik bilgisi nesnesi yerine açık metinli bir kullanıcı adı ve şifre gerektirir. Bu örnek, kullanıcı adının ve parolanın bir kimlik bilgisi nesnesinden nasıl çıkarılacağını gösterir.
Bu örnekteki Get-AllSQLDatabases işlevi, bir SQL sunucusunun tüm veritabanlarını sorgulamak için Invoke-Sqlcmd cmdlet'ini çağırır. İşlev, önceki örneklerde kullanılanla aynı özniteliğe sahip bir Kimlik Bilgisi parametresini tanımlar. Kullanıcı adı ve şifre $Credential değişkeninde mevcut olduğundan, bu değerleri Invoke-Sqlcmd ile kullanmak üzere çıkarabilirsiniz.
Kullanıcı adına, $Credential değişkeninin UserName özelliğinden ulaşılabilir. Şifreyi almak için $Credential nesnesinin GetNetworkCredential() yöntemini kullanmanız gerekir. Değerler, parametreleri Invoke-Sqlcmd'ye dağıtmak için kullanılan karma tablosuna eklenen değişkenlere çıkarılır.
function Get-AllSQLDatabases {
param(
$SQLServer,
[ValidateNotNull()]
[System.Management.Automation.PSCredential]
[System.Management.Automation.Credential()]
$Credential = [System.Management.Automation.PSCredential]::Empty
)
$UserName = $Credential.UserName
$Password = $Credential.GetNetworkCredential().Password
$splat = @{
UserName = $UserName
Password = $Password
ServerInstance = 'SQLServer'
Query = "Select * from Sys.Databases"
}
Invoke-Sqlcmd @splat
}
$credSplat = @{
TypeName = 'System.Management.Automation.PSCredential'
ArgumentList = 'duffney',('P@ssw0rd' | ConvertTo-SecureString -AsPlainText -Force)
}
$Credential = New-Object @credSplat
Get-AllSQLDatabases -SQLServer SQL01 -Credential $Credential
Sürekli öğrenme kimlik bilgileri yönetimi
Kimlik bilgileri nesnelerini güvenli bir şekilde oluşturmak ve saklamak zor olabilir. Aşağıdaki kaynaklar PowerShell kimlik bilgilerini korumanıza yardımcı olabilir.
- BetterCredentials
- Azure Anahtar Kasası
- Kasa Projesi
- Gizli Yönetim modülü

