PowerShell işlevlerine Kimlik Bilgisi desteği ekle

Not

Bu makalenin özgün sürümü, @joshduffney tarafından yazılan blogda yer almıştır. Bu makale bu siteye eklensin diye düzenlenmiş. PowerShell ekibi, josh'a bu içeriği bizimle paylaştığı için teşekkür ederiz. Lütfen duffney.io'daki blogunu inceleyin.

Bu makalede, PowerShell işlevlerine kimlik bilgisi parametrelerinin nasıl ekleneceği ve bunu neden yapmak istediğiniz gösterilir. Kimlik bilgisi parametresi, işlevi veya cmdlet'i farklı bir kullanıcı olarak çalıştırmanıza olanak sağlamaktır. En yaygın kullanım, işlevi veya cmdlet'i yükseltilmiş bir kullanıcı hesabı olarak çalıştırmaktır.

Örneğin, cmdlet'in New-ADUser bir Kimlik Bilgisi parametresi vardır. Bu parametre, etki alanında hesap oluşturmak için etki alanı yöneticisi kimlik bilgilerini sağlayabilirsiniz. PowerShell oturumunu çalıştıran normal hesabınızın zaten bu erişime sahip olmadığı varsayılır.

Kimlik bilgisi nesnesi oluşturma

PSCredential nesnesi, kullanıcı adı ve parola gibi bir dizi güvenlik kimlik bilgilerini temsil eder. Nesnesi, bu kimlik bilgisi nesnesinde kullanıcı hesabı olarak çalışan bir işleve parametre olarak geçirilebilir. Kimlik bilgisi nesnesi oluşturmanın birkaç yolu vardır. Kimlik bilgisi nesnesi oluşturmanın ilk yolu PowerShell cmdlet'ini Get-Credentialkullanmaktır. Parametresiz çalıştırdığınızda sizden bir kullanıcı adı ve parola istenir. İsterseniz bazı isteğe bağlı parametrelerle cmdlet'ini çağırabilirsiniz.

Etki alanı adını ve kullanıcı adını önceden belirtmek için Credential veya UserName parametrelerini kullanabilirsiniz. UserName parametresini kullandığınızda, bir İleti değeri de sağlamanız gerekir. Aşağıdaki kod cmdlet'ini kullanmayı gösterir. Kimlik bilgilerini birden çok kez kullanabilmek için kimlik bilgisi nesnesini bir değişkende de depolayabilirsiniz. Aşağıdaki örnekte, kimlik bilgisi nesnesi değişkeninde $Creddepolanı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 nesneleri 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. Ardından güvenli dizeyi ve kullanıcı adını yöntemine System.Management.Automation.PSCredential() geçirin.

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 belirten bir ileti uyarısı 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 yöntemine geçirmeniz PSCredential() gerekir. Aşağıdaki örnekte değişken $password , 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 nesneleri oluşturmayı bildiğinize göre, PowerShell işlevlerinize kimlik bilgisi parametreleri ekleyebilirsiniz.

Kimlik Bilgisi Parametresi Ekleme

Diğer parametrelerde olduğu gibi, işlevinizin bloğuna param ekleyerek başlarsınız. Mevcut PowerShell cmdlet'lerinin kullandığı parametreyi $Credential adlandırmanız önerilir. Parametresinin türü olmalıdır [System.Management.Automation.PSCredential].

Aşağıdaki örnekte adlı Get-Somethingbir işlevin parametre bloğu gösterilmektedir. İ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 bunu daha sağlam hale getirmek için ekleyebileceğiniz birkaç şey vardır.

  • Kimlik Bilgisi'ne [ValidateNotNull()]geçirilen değeri denetlemek için doğrulama özniteliğini ekleyin. Parametre değeri null ise, bu öznitelik işlevin geçersiz kimlik bilgileriyle yürütülmesini engeller.

  • ekleyin [System.Management.Automation.Credential()]. Bu, kullanıcı adını dize olarak geçirmenize ve parola için etkileşimli bir istem oluşturmanıza olanak tanır.

  • parametresi için $Credential varsayılan değeri olarak [System.Management.Automation.PSCredential]::Emptyayarlayın. İşleviniz bu $Credential nesneyi mevcut PowerShell cmdlet'lerine geçiriyor olabilirsiniz. İşlevinizin içinde çağrılan cmdlet'e null değer sağlamak hataya neden olur. Boş bir kimlik bilgisi nesnesi sağlanması bu hatayı önler.

İpucu

Kimlik bilgisi parametresi kabul eden bazı cmdlet'ler gerektiği gibi desteklemez [System.Management.Automation.PSCredential]::Empty . Geçici çözüm için Eski Cmdlet'lerle ilgilenme bölümüne bakın.

Kimlik bilgisi parametrelerini kullanma

Aşağıdaki örnekte kimlik bilgisi parametrelerinin nasıl kullanılacağı gösterilmektedir. Bu örnekte, Pester Book'un dışında olan adlı Set-RemoteRegistryValuebir işlev gösterilmektedir. Bu işlev, önceki bölümde açıklanan teknikleri kullanarak kimlik bilgisi parametresini tanımlar. İşlev, işlevi tarafından oluşturulan değişkeni kullanarak $Credential çağırırInvoke-Command. Bu, çalıştıran Invoke-Commandkullanıcıyı değiştirmenize olanak tanır. varsayılan değeri $Credential boş bir kimlik bilgisi olduğundan, işlev kimlik bilgileri sağlamadan çalıştırılabilir.

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, 'a Set-RemoteRegistryValuekimlik bilgileri sağlamanın farklı yöntemleri gösterilmektedir.

Kimlik bilgileri isteniyor

Çalışma Get-Credential zamanında parantez () içinde kullanmak, önce öğesinin Get-credential çalışmasına neden olur. Kullanıcı adı ve parola girmeniz istenir. Kullanıcı adı ve etki alanını önceden doldurmak için Credential veya UserName parametrelerini Get-credential kullanabilirsiniz. Aşağıdaki örnek, işleve parametre Set-RemoteRegistryValue geçirmek için splatting adlı bir teknik kullanır. Sıçrama 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)

Çalışma zamanında kimlik bilgisi alma

Kullanmak (Get-Credential) hantal görünüyor. Normalde, Kimlik Bilgisi parametresini yalnızca bir kullanıcı adıyla kullandığınızda, cmdlet otomatik olarak parolayı ister. [System.Management.Automation.Credential()] özniteliği bu davranışı etkinleştirir.

$remoteKeyParams = @{
    ComputerName = $env:COMPUTERNAME
    Path = 'HKLM:\SOFTWARE\Microsoft\WebManagement\Server'
    Name = 'EnableRemoteManagement'
    Value = '1'
}

Set-RemoteRegistryValue @remoteKeyParams -Credential duffney

Kimlik bilgileri iste

Not

Gösterilen kayıt defteri değerini ayarlamak için, bu örneklerde Windows'un Web Server özelliklerinin yüklü olduğu varsayılır. Install-WindowsFeature web-mgmt-tools ve gerekirse komutunu çalıştırınInstall-WindowsFeature Web-Server.

Değişkende kimlik bilgilerini sağlama

Ayrıca bir kimlik bilgisi değişkenini önceden doldurup işlevin Credential parametresine Set-RemoteRegistryValue geçirebilirsiniz. Jenkins, TeamCity ve Octopus Deploy gibi Sürekli Tümleştirme /Sürekli Dağıtım (CI/CD) araçlarıyla bu yöntemi kullanın. Jenkins'i kullanan bir örnek için, Windows'ta Jenkins ve PowerShell ile Otomatikleştirme - Bölüm 2'de Hodge'un blog gönderisini gözden geçirin.

Bu örnekte kimlik bilgisi nesnesini oluşturmak için .NET yöntemi ve parolayı geçirmek için güvenli bir dize kullanılı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 düz bir metin parolası kullanılarak oluşturulur. Daha önce bahsedilen tüm CI/CD,çalışma zamanında bu parolayı sağlamanın güvenli bir yöntemine 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ırma

$Credential Varsayılan olarak boş bir kimlik bilgisi nesnesi olduğundan, bu örnekte gösterildiği gibi komutunu 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 dize olarak kullanıcı adı ve parola parametrelerini ister. Bu sınırlamayı geçici olarak gidermenin 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 Invoke-Command yalnızca boş değilse öğesine ekler. Aksi takdirde, Credential parametresi olmadan öğesini 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ıçrama kullanma

Bu örnekte, eski cmdlet'i çağırmak için parametre sıçraması kullanılır. $Credential Nesnesi, karma tablosuna koşullu olarak sıçrama için eklenir ve betik bloğunun yinelenmesi gereğini Invoke-Command önler. İşlevlerin içine sıçrama hakkında daha fazla bilgi edinmek için Gelişmiş İşlevlerin İçinde Parametreleri Sıçrat 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, bir dizeyi parola olarak kabul eden bir cmdlet örneğidir. Invoke-Sqlcmd basit SQL ekleme, güncelleştirme ve silme deyimlerini çalıştırmanıza olanak tanır. Invoke-Sqlcmd daha güvenli bir kimlik bilgisi nesnesi yerine düz metin kullanıcı adı ve parola gerektirir. Bu örnekte, bir kimlik bilgisi nesnesinden kullanıcı adı ve parolanın nasıl ayıklanması gösterilmektedir.

Get-AllSQLDatabases Bu örnekteki işlev, tüm veritabanları için bir SQL sunucusunu sorgulamak için cmdlet'ini çağırırInvoke-Sqlcmd. işlevi, önceki örneklerde kullanılan öznitelikle bir Credential parametresi tanımlar. Değişkende kullanıcı adı ve parola bulunduğundan $Credential , ile Invoke-Sqlcmdkullanmak üzere bu değerleri ayıklayabilirsiniz.

Kullanıcı adı değişkeninin UserName özelliğinden $Credential kullanılabilir. Parolayı almak için nesnesinin GetNetworkCredential() yöntemini $Credential kullanmanız gerekir. Değerler, parametrelerin 'e sıçraması için kullanılan karma tabloya eklenen değişkenlere Invoke-Sqlcmdayıklanı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 bilgisi yönetimi

Kimlik bilgisi nesnelerini güvenli bir şekilde oluşturmak ve depolamak zor olabilir. Aşağıdaki kaynaklar PowerShell kimlik bilgilerini korumanıza yardımcı olabilir.