Главная > Powershell > Использование сплаттинга в Powershell

Использование сплаттинга в Powershell

Очень часто в Powershell нужно вызвать командлет, или функцию с большим набором параметров, которые неудобно располагать в одну строку из-за трудности восприятия.

Возьмём для примера не очень большую команду:

Get-WmiObject Win32_LogicalDisk -ComputerName server -Filter 'DriveType=3' `
    -Credential admin

Так как команда длинная и не помещается в отведённое ей место, я использовал символ “`”для того, чтобы перенести её на другую строку. Можно понаставить таких символов, чтобы эта же команда выглядела более читабельно:

Get-WmiObject Win32_LogicalDisk `
    -ComputerName server `
    -Filter 'DriveType=3' `
    -Credential admin

Но, “best practice”  является использование такого разрыва только в самых крайних случаях. А ещё лучше обходиться вообще без них. И здесь на помощь приходит сплаттинг.

Что же такое сплаттинг?

Под непонятным словом сплаттинг (Splatting) понимают относительно новый способ передачи параметров в командлеты и функции. Заключается он в передаче параметров через хеш-таблицу. В такой хеш-таблице ключами являются имена параметров, а значениями – значения, которые передаются в эти параметры.

Таким образом хеш-таблица параметров для нашего примера будет выглядеть следующим образом:

$params = @{
                'Class' = 'Win32_LogicalDisk'
                'ComputerName' = 'server'
                'Filter' = 'DriveType=3'
                'Credential' = 'admin'
           }

После чего остаётся вызвать нужный командлет и передать ему эту хеш-таблицу:

Get-WmiObject @params

Следует обратить внимание на то, при передаче хеш-таблицы в командлет переменная, содержащая нашу хеш-таблицу, начинается не со знака “$”, а с “@”.

Так как передаваемые параметры – это самая обыкновенная хеш-таблица, то можно создать пустую таблицу, и потом наполнять её свойствами. Например:

$LogFiles = @{}
$LogFiles.Path = 'D:\test'
$LogFiles.Recurse = $true
$LogFiles.Filter = '*.log'

Get-ChildItem @LogFiles

 

Рассмотрим ещё один более интересный пример:

function Get-ComputerInfo
{
    param
    (
        $ComputerName,
        [switch]$Credential
    )

    if ($PSBoundParameters.ContainsKey('Credential'))
    {
        $PSBoundParameters.Credential = Get-Credential admin
    }

    $User = Get-WmiObject Win32_ComputerSystem @PSBoundParameters |
        Select-Object -ExpandProperty UserName
    $OS = Get-WmiObject Win32_OperatingSystem @PSBoundParameters |
        Select-Object -ExpandProperty CSName
        
    "`nПользователь:`t$User"
    "Имя компьютера:`t$OS `n"
}

Функция Get-ComputerInfo получает некую информацию о компьютере. Функция работает с локальным ПК, удалённым, и поддерживает ввод учётных данных.

Если запустить функцию без параметров она будет собирать информацию о локальном ПК (как обычный вызов Get-WmiObject). С использованием параметра ComputerName можно собрать информацию об удалённом ПК, если же добавить параметр Credential, то можно ввести альтернативные учётные данные.

При классическом подходе (без использования сплаттинга) этот код пришлось бы переписать трижды: для сбора информации о локальном ПК, об удалённом ПК и об удалённом ПК с альтернативными учётными данными.

В данном примере используется сплаттинг и служебная переменная $PSBoundParameters.

На всякий случай (согласно справке из Powershell):

$PSBoundParameters содержит словарь активных параметров и их текущих значений. Значение этой переменной действительно только в области объявления параметров, включая скрипт или функцию. Можно использовать эту переменную для отображения или изменения текущих значений параметров или для передачи значений параметров другому скрипту или функции.

Тут следует учитывать один важный нюанс.

Перед вызовом командлета с использованием сплаттинга из хеш-таблицы, содержащей параметры нужно удалить значения тех параметров, которых нет в вызываемом командлете, иначе будет горе выскочит ошибка.

Например, у нашей функции присутствует ещё какой-то параметр SomethingElse. Так как командлет Get-WmiObject не имеет такого параметра, то перед его вызовом этот параметр нужно удалить из передаваемой хеш-таблицы (в данном случае – $PSBoundParameters). Т.е. наша функция несколько изменится:

function Get-ComputerInfo
{
    param
    (
        $ComputerName,
        [switch]$Credential,
        $SomethingElse
    )

    $null = $PSBoundParameters.Remove('SomethingElse')
    
    if ($PSBoundParameters.ContainsKey('Credential'))
    {
        $PSBoundParameters.Credential = Get-Credential admin
    }

    $User = Get-WmiObject Win32_ComputerSystem @PSBoundParameters |
        Select-Object -ExpandProperty UserName
    $OS = Get-WmiObject Win32_OperatingSystem @PSBoundParameters |
        Select-Object -ExpandProperty CSName
        
    "`nПользователь:`t$User"
    "Имя компьютера:`t$OS `n"
}

Преимущества сплаттинга очевидны: он позволяет красиво и наглядно отформатировать код без ущерба производительности, все параметры и их значения удобно располагаются в одном месте.

Реклама
Рубрики:Powershell Метки:
  1. Комментариев нет.
  1. 05/09/2014 в 14:14

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s

%d такие блоггеры, как: