Sdílet prostřednictvím


Přidání podpory přihlašovacích údajů do funkcí PowerShellu

Poznámka:

původní verze tohoto článku se objevila na blogu napsaném @joshduffney. Tento článek byl upraven pro zahrnutí na tento web. Tým PowerShellu díky Joshi za sdílení tohoto obsahu s námi. Prosím, podívejte se na jeho blog na duffney.io.

V tomto článku se dozvíte, jak přidat parametry přihlašovacích údajů do funkcí PowerShellu a proč chcete. Parametr přihlašovacích údajů umožňuje spustit funkci nebo rutinu jako jiný uživatel. Nejběžnějším použitím je spuštění funkce nebo rutiny jako uživatelského účtu se zvýšenými oprávněními.

Například rutina New-ADUser má parametr Credentials, který můžete použít k zadání přihlašovacích údajů správce domény pro vytvoření účtu v doméně. Za předpokladu, že váš normální účet, na kterém běží relace PowerShellu, tento přístup ještě nemá.

Vytvoření objektu přihlašovacích údajů

Objekt PSCredential představuje sadu přihlašovacích údajů zabezpečení, jako je uživatelské jméno a heslo. Objekt lze předat jako parametr funkci, která se spouští jako uživatelský účet v daném objektu přihlašovacích údajů. Existuje několik způsobů, jak vytvořit objekt přihlašovacích údajů. Prvním způsobem vytvoření objektu přihlašovacích údajů je použití rutiny PowerShellu Get-Credential. Když spustíte bez parametrů, zobrazí se výzva k zadání uživatelského jména a hesla. Nebo můžete zavolat rutinu cmdlet s některými volitelnými parametry.

Pokud chcete předem zadat název domény a uživatelské jméno, můžete použít parametry přihlašovacích údajů nebo UserName. Pokud použijete parametr UserName, musíte také zadat hodnotu Message. Následující kód ukazuje použití cmdletu. Objekt přihlašovacích údajů můžete také uložit do proměnné, abyste mohli přihlašovací údaje používat vícekrát. V následujícím příkladu je objekt přihlašovacích údajů uložen v proměnné $Cred.

$Cred = Get-Credential
$Cred = Get-Credential -Credential domain\user
$Cred = Get-Credential -UserName domain\user -Message 'Enter Password'

Někdy nemůžete použít interaktivní metodu vytváření objektů přihlašovacích údajů zobrazených v předchozím příkladu. Většina nástrojů automatizace vyžaduje neinteraktivní metodu. Pokud chcete vytvořit přihlašovací údaje bez zásahu uživatele, vytvořte zabezpečený řetězec obsahující heslo. Pak předejte zabezpečený řetězec a uživatelské jméno metodě System.Management.Automation.PSCredential().

Pomocí následujícího příkazu vytvořte zabezpečený řetězec obsahující heslo:

ConvertTo-SecureString "MyPlainTextPassword" -AsPlainText -Force

Jsou vyžadovány parametry AsPlainText i Vynucení parametrů. Bez těchto parametrů obdržíte zprávu, která vás varuje, že byste neměli předávat prostý text do zabezpečeného řetězce. PowerShell toto upozornění vrátí, protože heslo ve formátu prostého textu se zaznamená do různých protokolů. Jakmile vytvoříte zabezpečený řetězec, musíte ho předat metodě PSCredential() k vytvoření objektu přihlašovacích údajů. V následujícím příkladu proměnná $password obsahuje zabezpečený řetězec $Cred obsahuje objekt pověření.

$password = ConvertTo-SecureString "MyPlainTextPassword" -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential ("username", $password)

Teď, když víte, jak vytvářet objekty přihlašovacích údajů, můžete do funkcí PowerShellu přidat parametry přihlašovacích údajů.

Přidání parametru přihlašovacích údajů

Stejně jako jakýkoli jiný parametr začnete tím, že ho přidáte do param bloku funkce. Doporučujeme pojmenovat parametr $Credential, protože to používají existující cmdlety PowerShell. Typ parametru by měl být [System.Management.Automation.PSCredential].

Následující příklad ukazuje blok parametrů pro funkci s názvem Get-Something. Má dva parametry: $Name a $Credential.

function Get-Something {
    param(
        $Name,
        [System.Management.Automation.PSCredential]$Credential
    )

Kód v tomto příkladu stačí k tomu, aby měl funkční parametr přihlašovacích údajů, ale existuje několik věcí, které můžete přidat, aby byl robustnější.

  • Přidejte atribut ověření [ValidateNotNull()] a zkontrolujte, jestli se hodnota předávaná do přihlašovacího údaje. Pokud je hodnota parametru null, zabrání tento atribut funkci v provádění s neplatnými přihlašovacími údaji.

  • Přidat [System.Management.Automation.Credential()]. To vám umožní předat uživatelské jméno jako řetězec a mít interaktivní výzvu k zadání hesla.

  • Nastavte výchozí hodnotu parametru $Credential na [System.Management.Automation.PSCredential]::Empty. Vaše funkce může tento objekt $Credential předat existujícím cmdletům PowerShellu. Poskytnutí hodnoty null rutině volané uvnitř vaší funkce způsobí chybu. Poskytnutí prázdného objektu přihlašovacích údajů zabrání této chybě.

Návod

Některé rutiny, které přijímají parametr přihlašovacích údajů, nepodporují [System.Management.Automation.PSCredential]::Empty tak, jak by měly. Podívejte se na část Řešení starších cmdletů pro alternativní řešení.

Použití parametrů přihlašovacích údajů

Následující příklad ukazuje, jak používat parametry přihlašovacích údajů. Tento příklad ukazuje funkci s názvem Set-RemoteRegistryValue, která je mimo The Pester Book. Tato funkce definuje parametr přihlašovacích údajů pomocí technik popsaných v předchozí části. Funkce volá Invoke-Command pomocí proměnné $Credential vytvořené funkcí. To vám umožní změnit uživatele, který používá Invoke-Command. Vzhledem k tomu, že výchozí hodnota $Credential je prázdný přihlašovací údaj, může funkce běžet bez zadání přihlašovacích údajů.

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
}

Následující části ukazují různé metody poskytování přihlašovacích údajů Set-RemoteRegistryValue.

Výzva k zadání přihlašovacích údajů

Použití Get-Credential v závorkách () během provádění způsobí, že se Get-Credential spustí jako první. Zobrazí se výzva k zadání uživatelského jména a hesla. K předvyplnění uživatelského jména a domény můžete použít parametry Credential nebo UserNameGet-Credential. Následující příklad používá metodu splatting k předání parametrů Set-RemoteRegistryValue funkci. Další informace o splattingu najdete v about_Splatting článku.

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

Set-RemoteRegistryValue @remoteKeyParams -Credential (Get-Credential)

Získat přihlašovací údaje za běhu

Použití (Get-Credential) se zdá být těžkopádné. Obvykle když použijete parametr Credential pouze s uživatelským jménem, rutina automaticky vyzve k zadání hesla. Atribut [System.Management.Automation.Credential()] umožňuje toto chování.

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

Set-RemoteRegistryValue @remoteKeyParams -Credential duffney

Výzva k zadání přihlašovacích údajů

Poznámka:

Pokud chcete nastavit zobrazenou hodnotu registru, tyto příklady předpokládají, že máte nainstalované funkce webového serveru systému Windows. V případě potřeby spusťte Install-WindowsFeature Web-Server a Install-WindowsFeature web-mgmt-tools.

Zadání přihlašovacích údajů v proměnné

Také můžete předem naplnit proměnnou přihlašovacích údajů a předat ji parametru přihlašovací údaje funkce Set-RemoteRegistryValue. Tuto metodu použijte s nástroji kontinuální integrace / průběžného nasazování (CI/CD), jako jsou Jenkins, TeamCity a Octopus Deploy. Příklad použití Jenkinse, podívejte se na Hodgeho blogový příspěvek Automatizace s Jenkinsem a PowerShellem ve Windows – část 2.

Tento příklad používá metodu .NET k vytvoření objektu přihlašovacích údajů a zabezpečeného řetězce pro předání hesla.

$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

V tomto příkladu se zabezpečený řetězec vytvoří pomocí hesla s jasným textem. Všechny dříve zmíněné CI/CD mají zabezpečenou metodu poskytování tohoto hesla za běhu. Při použití těchto nástrojů nahraďte heslo ve formátu prostého textu proměnnou definovanou v nástroji CI/CD, který používáte.

Spustit bez přihlašovacích údajů

Vzhledem k tomu, že $Credential má výchozí hodnotu prázdného objektu přihlašovacích údajů, můžete tento příkaz spustit bez přihlašovacích údajů, jak ukazuje tento příklad:

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

Set-RemoteRegistryValue @remoteKeyParams

Práce se staršími rutinami

Ne všechny rutiny podporují objekty přihlašovacích údajů nebo povolují prázdné přihlašovací údaje. Místo toho chce rutina parametry uživatelského jména a hesla jako řetězce. Existuje několik způsobů, jak toto omezení obejít.

Použití funkce if-else ke zpracování prázdných přihlašovacích údajů

V tomto scénáři rutina, kterou chcete spustit, nepřijímá prázdný objekt přihlašovacích údajů. Tento příklad přidá parametr credential k Invoke-Command pouze v případě, že není prázdný. V opačném případě spustí Invoke-Command bez parametru credential.

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
        }
    }
}

Použití splattingu ke zpracování prázdných přihlašovacích údajů

V tomto příkladu se k volání staršího cmdletu používá distribuce parametrů. Objekt $Credential je podmíněně přidán do tabulky hash pro splatting a zabraňuje nutnosti opakovat blok skriptu Invoke-Command. Další informace o splattingu uvnitř funkcí najdete v blogovém příspěvku Splatting Parameters Inside Advanced Functions.

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
}

Práce s řetězcovými hesly

Cmdlet Invoke-Sqlcmd je příkladem cmdletu, který přijímá řetězec jako heslo. Invoke-Sqlcmd umožňuje spouštět jednoduché příkazy SQL insert, update a delete. Invoke-Sqlcmd vyžaduje uživatelské jméno a heslo ve formátu čistého textu, místo bezpečnějšího objektu přihlašovacích údajů. Tento příklad ukazuje, jak extrahovat uživatelské jméno a heslo z objektu přihlašovacích údajů.

Funkce Get-AllSQLDatabases v tomto příkladu volá rutinu Invoke-Sqlcmd k dotazování sql serveru pro všechny její databáze. Funkce definuje credential parametr se stejným atributem použitým v předchozích příkladech. Vzhledem k tomu, že uživatelské jméno a heslo existují v proměnné $Credential, můžete tyto hodnoty extrahovat pro použití s Invoke-Sqlcmd.

Uživatelské jméno je k dispozici z vlastnosti UserName proměnné $Credential. Chcete-li získat heslo, musíte použít GetNetworkCredential() metodu $Credential objektu. Hodnoty se extrahují do proměnných, které se přidají do hašovací tabulky používané ke splattingu parametrů pro Invoke-Sqlcmd.

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

Pokračující správa osvědčení ve vzdělávání

Vytváření a ukládání objektů přihlašovacích údajů bezpečně může být obtížné. Následující zdroje informací vám můžou pomoct s údržbou přihlašovacích údajů PowerShellu.