2015-06-05 3 views
1

Я разработал набор функций, которые будут использоваться нашей командой Desktop и Service Desk, и развернул специальный профиль ISE для PowerShell каждого сотрудника, который загружает модуль файл, содержащий все функции.вызов пользовательских функций из меню надстроек в Powershell ISE

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

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

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

env:PSModulePath = $env:PSModulePath + ";\\remotelocation\Modules" 
$CommandList = Get-Command -Module "CompanyModules" | Select-Object Name -ExpandProperty Name 

function Add-ISEMenuItem([String]$MenuName,[String]$Name,[ScriptBlock]$Script,[String]$Shortcut) 
{ 
    try{ 
     if ($Shortcut) { $Menus[$MenuName].Submenus.Add($Name, $Script, $Shortcut) | Out-Null } 
     else { $Menus[$MenuName].Submenus.Add($Name, $Script,$null) | Out-Null } 
    } 
    catch { 
     Write-Warning $_ 
    } 
} 

function Add-ISESubMenu([String]$MenuName,[String]$Name) 
{ 
    try 
    { 
     if (-not ($menus -contains $MenuName)) 
     { 
      $menus[$Name] = $menus[$MenuName].SubMenus.Add($Name,$null,$null) 
     } 
     else 
     { 
      throw "Menu name already used" 
     } 
    } 
    catch 
    { 
     Write-Warning $_ 
    } 
}  

############################################################################## 
# Setting up the PowerShell_ISE environment 
############################################################################# 

$menus = @{} 
$menus["AddOns"] = $psISE.CurrentPowerShellTab.AddOnsMenu 

Add-ISESubMenu -MenuName "AddOns" -Name "Company Modules" 

$count = $CommandList.count 

for ($i = 0; $i -lt $count; $i++) 
{ 
    $cmd = $CommandList[$i] 
    Add-ISEMenuItem -MenuName "Company Modules" -Name "$cmd" -Script { $cmd[0] } 
} 

Все хорошо до сих пор, когда загружается профиль, подменю создается с именем «Модули компании» и каждая функция отображается в этом меню - однако при выборе функции, вместо выполнения функции, ее просто расширяет значение $ cmd, которое всегда является только значением String для первого имени функции.

Я понимаю, что это связано с значением -Script и его требованием иметь его значение, содержащееся в фигурных скобках. Но я не могу для жизни понять, как преодолеть это.

Есть ли вообще способ, чтобы функции выполнялись из меню надстроек точно так же, как если бы вы набрали их вручную в консоли?

Заранее спасибо.

ответ

0
$CommandList = Get-Command -Module "CompanyModules" | Select-Object Name -ExpandProperty Name 

То, что вы сделали здесь, вы только получили название каждой функции в $CommandList.

Таким образом, вместо давайте изменить его к этому:

$CommandList = Get-Command -Module "CompanyModules" 

получить весь объект команды.

Затем в нижней части сценария:

$CommandList | ForEach-Object { 
    Add-ISEMenuItem -MenuName "Company Modules" -Name $_.Name -Script ([ScriptBlock]::Create($_.Definition)) 
} 

Заметим, что вы можете использовать свой for цикл итерировать $CommandList, если вы хотите, я просто думаю, что это проще.

Недвижимость .Definition по функции, возвращаемой Get-Command содержит [String] кода, который составляет эту функцию. Вы cna превратите это в ScriptBlock, используя [ScriptBlock]::Create().

То, что вы делали раньше, было в основном просто передачей нового скриптового блока, в котором было напечатано только имя функции.

+0

Thanks @briantist Имеет большой смысл - мне действительно нужно помнить, насколько ценным становится член! Последняя вещь - код определенно выполнен, но есть ли способ подавить определение функции, сбрасываемое на экран? – DangerBen

+0

Я не уверен, но, я думаю, нет.Это то же поведение, что и при выполнении файла, который не сохраняется, поэтому я предполагаю, что он обрабатывает его внутренне таким же образом. – briantist