Windows PowerShell: Создайте лучшую функцию

OSzone.net » Microsoft » PowerShell » Windows PowerShell: Создайте лучшую функцию
Автор: Дон Джонс
Иcточник: TechNet Magazine
Опубликована: 07.12.2011

В Windows PowerShell 2.0 компания Microsoft представила новый тип функции — «расширенная функция» (advanced function). Многие называют их «сценарными командлетами». Идея создания этих функций заключается в том, чтобы использовать упрощенный язык сценариев Windows PowerShell для создания чего-то, что бы выглядело, работало, пахло и вело себя почти так же, как настоящий командлет Windows PowerShell.

Ясно, что не всем потребуется создавать повторно используемые инструменты для себя и своих коллег. Однако если вы все-таки создаете такие инструменты, расширенные функции — единственный способ решения этой задачи. В сущности, я меняю курсы, которые читаю слушателям, с тем чтобы преподавать создание только этого вида функций.

Так как расширенные функции работают во многом так же, как настоящие командлеты, качественно сделанная функция может быть удобнее для других, так как она «имитирует» стандартную работу командной оболочки. Для этого вот вам шаблон, который можно использовать для более быстрого создания таких расширенных функций:

function Get-Something {
  <#
  .SYNOPSIS
  Описание функции
  .DESCRIPTION
  Более подробное описание функции
  .EXAMPLE
  Пример использования функции
  .EXAMPLE
  Еще один пример использования функции
  .PARAMETER computername
  Имя запрашиваемого компьютера. Только одно имя.
  .PARAMETER logname
  Имя файла, в который надо записывать имена сбойных компьютеров. Имя по умолчанию - errors.txt.
  #>
  [CmdletBinding()]
  param
  (
    [Parameter(Mandatory=$True,
    ValueFromPipeline=$True,
    ValueFromPipelineByPropertyName=$True,
      HelpMessage='What computer name would you like to target?')]
    [Alias('host')]
    [ValidateLength(3,30)]
    [string[]]$computername,

    [string]$logname = 'errors.txt'
  )

  begin {
  write-verbose "Deleting $logname"
    del $logname -ErrorActionSilentlyContinue
  }

  process {

    write-verbose "Beginning process loop"

    foreach ($computer in $computername) {
      Write-Verbose "Processing $computer"
      # используйте $computer для обращения только к одному компьютеру


      # создаем хеш-таблицу с возвращаемой информацией
      $info = @{
        'info1'=$value1;
        'info2'=$value2;
        'info3'=$value3;
        'info4'=$value4
      }
      Write-Output (New-Object –TypenamePSObject –Prop $info)
    }
  }
}

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

Этот шаблон годится для любой расширенной функции, которая должна получать информацию, но не вносить никаких изменений в состояние системы. В расширенной функции, которая должна менять состояние системы, надо реализовать несколько дополнительных элементов. Для этого вот вам второй шаблон:

function Do-Something {
  <#
  .SYNOPSIS
  Описание функции
  .DESCRIPTION
  Более подробное описание функции
  .EXAMPLE
  Пример использования функции
  .EXAMPLE
  Еще один пример использования функции
  .PARAMETER computername
  Имя запрашиваемого компьютера. Только одно имя.
  .PARAMETER logname
  Имя файла, в который надо записывать имена сбойных компьютеров. Имя по умолчанию - errors.txt.
  #>
  [CmdletBinding(SupportsShouldProcess=$True,ConfirmImpact='Low')]
  param
  (
    [Parameter(Mandatory=$True,
    ValueFromPipeline=$True,
    ValueFromPipelineByPropertyName=$True,
      HelpMessage='What computer name would you like to target?')]
    [Alias('host')]
    [ValidateLength(3,30)]
    [string[]]$computername,

    [string]$logname = 'errors.txt'
  )

  begin {
  write-verbose "Deleting $logname"
    del $logname -ErrorActionSilentlyContinue
  }

  process {

    write-verbose "Beginning process loop"

    foreach ($computer in $computername) {
      Write-Verbose "Processing $computer"
      if ($pscmdlet.ShouldProcess($computer)) {
        # здесь надо использовать $computer
      }
    }
  }
}

В этом шаблоне надо изменить параметр ConfirmImpact. Надо указать возможную опасность расширенной функции. При выполнении минимальных изменений, например изменения атрибута «только для чтения» в файле ReadOnly параметру ConfirmImpact можо присвоить значение Low (то есть низкий уровень важности). А у операции перезагрузки компьютера уровень важности может быть высоким, или High. Windows PowerShell использует этот параметр вместе со встроенной переменной $ConfirmPreference оболочки для определения, нужно ли отображать для пользователя предупреждения и требовать подтверждения операции.

Отмечено, где собственно надо выполнять операцию, используя в качестве целевого компьютер, указанный в переменной $computer. Это место обернуто конструкцией «If», в которой используется объект $pscmdlet. Если эту функцию запустить с параметрами –whatif или –confirm (которые она должна поддерживать), $pscmdlet обеспечит вывод типа «что если» или сгенерирует предупреждение типа «вы уверены?».

Оба шаблона также поддерживают параметр –verbose и использование Write-Verbose для генерации сообщений о состоянии при выполнении функции. Ясно, что не все функции работают с компьютерами. Могут потребоваться параметры, принимающие имена файлов, имена пользователей или другую информацию. Надо просто соответствующим образом поменять объявления параметров.

Информацию об атрибутах параметров, таких как проверка, обязательность, конвейерный ввод и других, можно получить, выполнив в оболочке команду help about_functions_advanced_parameter. Пользуйтесь на здоровье!


Ссылка: http://www.oszone.net/16665/