我开发了一系列功能,供桌面和服务台团队使用,并为每个加载包含所有功能的模块文件的员工部署了自定义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 :(得分: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]
代码。您可以使用[ScriptBlock]::Create()
将其转换为ScriptBlock。
之前您正在做的事情基本上只是传递一个新的脚本块,只打印出函数的名称。