Funkcje PowerShell: Kluczowe Kroki do Perfekcji

utworzone przez | gru 2, 2023 | Uncategorized | 0 komentarzy

W dzisiejszym świecie automatyzacji i programowania, pisanie funkcji w PowerShell staje się nieodłączną częścią pracy każdego administratora systemu czy cloud inżyniera. Aby jednak stworzyć efektywną i łatwą w użyciu funkcję, warto przestrzegać pewnych kroków i zasad. W poniższym wpisie omówimy dziesięć kroków, które pomogą Ci w tworzeniu funkcji PowerShell od podstaw. Od zdefiniowania celu po udostępnienie gotowego kodu – przewodnik ten poprowadzi Cię przez cały proces.

Krok 1: Zdefiniuj Jasny Cel

Zanim zaczniesz pisać funkcję, dokładnie zastanów się, jaki jest jej cel. Jakie zadanie lub zadania ma ona wykonać? Mówi się, że dobry plan to połowa sukcesu, więc przemyśl swoją funkcję przed napisaniem pierwszych linii kodu.

Krok 2: Wybierz Zgodną Nazwę

Wybierz nazwę dla funkcji, która jasno odzwierciedla jej cel. Zaleca się stosowanie konwencji czasownik-rzeczownik dla nazw funkcji w PowerShell. Na przykład Get-MyData lub Invoke-Task.

function Get-AzDevOpsRepository {
    [cmdletbinding()]
}

Krok 3: Zadeklaruj Parametry

Jeśli wystarczająco dużo czasu spędziłeś w kroku 1 to dokładnie wiesz jakich danych potrzebujesz na wejściu, aby funkcja wykonania swoje zadania. Użyj słowa kluczowego param do deklaracji parametrów.

Na przykład:

function Get-AzDevOpsRepository {
    [cmdletbinding()]
    param(
        $organizationName,
        $projectName,
        $token
    )
}

Krok 4: Obsługuj Walidację Parametrów

Jeśli masz zdefiniowane parametry, dodaj walidację wartości wejściowych, aby upewnić się, że spełniają oczekiwane kryteria. PowerShell dostarcza różne atrybuty do walidacji parametrów, takie jak [ValidateNotNullOrEmpty()] lub [ValidateRange()].

Użyj tych atrybutów, aby zwiększyć odporność twojej funkcji, jak również określ typ danych dla Twoich danych wejściowych.

function Get-AzDevOpsRepository {
    [cmdletbinding()]
    param(
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$organizationName,
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$projectName,
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [securestring]$token
    )
}

Więcej na ten temat znajdziesz tutaj – 3 sposoby sprawdzania wartośc parametrów w PowerShell.

Krok 5: Wprowadź Logikę

Napisz podstawową logikę funkcji. Rozbij złożone zadania na mniejsze, łatwiejsze do zarządzania kroki. Wykorzystuj wbudowane cmdlety i funkcje, kiedy to konieczne, oraz rozważ obsługę błędów, aby zwiększyć odporność funkcji.

Do realizacji logiki funkcji, staraj się wykorzystywać natywnie dostępne polecenia, aby unikać zależności od „zewnętrznych” modułów.

function Get-AzDevOpsRepository {
    [cmdletbinding()]
    param(
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$organizationName,
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$projectName,
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [securestring]$token
    )
 
    $insecureToken = $token| ConvertFrom-SecureString -AsPlainText
    $B64Token = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("`:$insecureToken"))
    $Headers = @{
        "Authorization" = "Basic $B64Token"
        "Content-Type"  = "application/json"
        "Accept"        = "application/json"
    }
 
    $Url = "https://dev.azure.com/{0}/{1}/_apis/git/repositories?api-version=4.1" -f $organizationName, $projectName
    $Response = Invoke-RestMethod -Uri $Url -Headers $Headers -Method Get -StatusCodeVariable StatusCode
    if($StatusCode -eq 200) {
       Write-Output $Response.value
    }
    else {
        Write-Output $Response
    }
}

Krok 6: Wykorzystaj Obsługę Potoku

Zaprojektuj funkcję tak, aby działała płynnie z potokiem PowerShell. Pozwala to użytkownikom łączyć ze sobą wiele poleceń, zwiększając elastyczność i użyteczność twojej funkcji.

function Get-AzDevOpsRepository {
    [cmdletbinding()]
    param(
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$organizationName,
 
        # ważne, atrybut ValueFromPipeline i ValueFromPipelineByPropertyName oznaczają, które 
        # parametry będą przekazywane w potoku
        [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [ValidateNotNullOrEmpty()]
        [string]$projectName,
 
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [securestring]$token
    )
 
    # niezbędny blog process 
    process {
        $insecureToken = $token | ConvertFrom-SecureString -AsPlainText
        $B64Token = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("`:$insecureToken"))
        $Headers = @{
            "Authorization" = "Basic $B64Token"
            "Content-Type"  = "application/json"
            "Accept"        = "application/json"
        }
 
        $Url = "https://dev.azure.com/{0}/{1}/_apis/git/repositories?api-version=4.1" -f $organizationName, $projectName
        $Response = Invoke-RestMethod -Uri $Url -Headers $Headers -Method Get -StatusCodeVariable StatusCode
        if ($StatusCode -eq 200) {
            Write-Output $Response.value
        }
        else {
            Write-Output $Response
        }
    }
}

Krok 7: Zastanów się nad Wyjściem

Zdecyduj, co twoja funkcja powinna zwracać. Może to być określony obiekt, prostą wartość lub w ogóle nic. Jednolite formaty wyjścia sprawiają, że funkcja jest przewidywalna i łatwiejsza w użyciu.

Ja preferuję obiekt na wyjściu, ułatwia nie tylko przekazywanie bardziej skomplikowanych danych, ale także późniejsze ich przetwarzanie.

function Get-AzDevOpsRepository {
    [cmdletbinding()]
    param(
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$organizationName,
 
        # ważne, atrybut ValueFromPipeline i ValueFromPipelineByPropertyName oznaczają, które 
        # parametry będą przekazywane w potoku
        [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [ValidateNotNullOrEmpty()]
        [string]$projectName,
 
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [securestring]$token
    )
 
    # niezbędny blog process 
    process {
        $insecureToken = $token | ConvertFrom-SecureString -AsPlainText
        $B64Token = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("`:$insecureToken"))
        $Headers = @{
            "Authorization" = "Basic $B64Token"
            "Content-Type"  = "application/json"
            "Accept"        = "application/json"
        }
 
        $Url = "https://dev.azure.com/{0}/{1}/_apis/git/repositories?api-version=4.1" -f $organizationName, $projectName
        $Response = Invoke-RestMethod -Uri $Url -Headers $Headers -Method Get -StatusCodeVariable StatusCode
        if ($StatusCode -eq 200) {
 
            $Response.value | ForEach-Object {
                Write-Output ([PSCustomObject][Ordered]@{
                    Name = $_.Name
                    SizeMB = $_.size / 1MB
                    isDisabled = $_.isDisabled
                    lastUpdateTime= $_.project.lastUpdateTime
                })
            }
 
        }
        else {
            Write-Output $Response
        }
    }
}

Krok 8: Napisz Pomoc z Użyciem Komentarzy

Udokumentuj swoją funkcję, używając komentarzy. Opisz cel, parametry, dane wejściowe, dane wyjściowe i przykłady. Ta dokumentacja jest kluczowa dla użytkowników, którzy chcą zrozumieć i używać twojej funkcji. Na przykład:

<#
.SYNOPSIS
    Pobiera informacje o repozytoriach Azure DevOps na podstawie dostarczonych parametrów.
.DESCRIPTION
    Funkcja ta łączy się z interfejsem API Azure DevOps, aby pobrać informacje o repozytoriach.
.PARAMETER organizationName
    Nazwa organizacji Azure DevOps.
.PARAMETER projectName
    Nazwa projektu w Azure DevOps.
.PARAMETER token
    Token uwierzytelniający dostępu do Azure DevOps (SecureString).
.EXAMPLE
    $InsecureToken = 'token' | ConvertTo-SecureString -AsPlainText -Force
    'Testy' | Get-AzDevOpsRepository -organizationName 'Organizacja' -token $Insecuretoken
#>
function Get-AzDevOpsRepository {
    [cmdletbinding()]
    param(
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$organizationName,
 
        # ważne, atrybut ValueFromPipeline i ValueFromPipelineByPropertyName oznaczają, które 
        # parametry będą przekazywane w potoku
        [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [ValidateNotNullOrEmpty()]
        [string]$projectName,
 
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [securestring]$token
    )
 
    # niezbędny blog process 
    process {
        # Konwersja zabezpieczonego tokena na niezabezpieczony i kodowanie Base64
        $insecureToken = $token | ConvertFrom-SecureString -AsPlainText
        $B64Token = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("`:$insecureToken"))
        $Headers = @{
            "Authorization" = "Basic $B64Token"
            "Content-Type"  = "application/json"
            "Accept"        = "application/json"
        }
 
        $Url = "https://dev.azure.com/{0}/{1}/_apis/git/repositories?api-version=4.1" -f $organizationName, $projectName
        $Response = Invoke-RestMethod -Uri $Url -Headers $Headers -Method Get -StatusCodeVariable StatusCode
 
        # Sprawdzenie kodu statusu odpowiedzi
        if ($StatusCode -eq 200) {
 
            $Response.value | ForEach-Object {
                Write-Output ([PSCustomObject][Ordered]@{
                    Name = $_.Name
                    SizeMB = $_.size / 1MB
                    isDisabled = $_.isDisabled
                    lastUpdateTime= $_.project.lastUpdateTime
                })
            }
 
        }
        else {
            Write-Output $Response
        }
    }
}

Krok 9: Testuj Dokładnie

Przetestuj swoją funkcję z różnymi danymi wejściowymi, aby upewnić się, że zachowuje się zgodnie z oczekiwaniami. Ten krok jest kluczowy dla identyfikacji i naprawienia ewentualnych problemów przed udostępnieniem funkcji innym.

Krok 10: Udostępnij i Udoskonalaj

Gdy jesteś pewien swojej funkcji, rozważ podzielenie się nią z innymi. Możesz udostępnić ją jako część skryptu, modułu lub dostarczyć kod bezpośrednio. Bądź otwarty na opinie i wprowadzaj zmiany w oparciu o doświadczenia i sugestie użytkowników.

Podsumowanie

Tworzenie funkcji w PowerShell to fascynujące wyzwanie, ale wymaga ścisłego przestrzegania kluczowych kroków. Zacznij od jasno zdefiniowanego celu, odpowiedniej nazwy i deklaracji parametrów. Dodaj walidację, obsługę potoku i skuteczną obsługę wyjątków, aby zwiększyć funkcjonalność i niezawodność. Testowanie i udokumentowanie są kluczowe przed udostępnieniem funkcji.

Photo by Brett Jordan on Unsplash

Azure PowerShell Kit

JUŻ WKRÓTCE!

Odkryj potęgę połączenia PowerShell z Azure! Gotowe zapytania Kusto, skrypty PowerShell i unikalne dodatki ułatwią Ci efektywne zarządzanie zasobami w chmurze