我的XML文件包含:
<Setting>
<Application Id="Main_Form" Name="Office365: Run scripts">
<task Id="1" Script="SPO-SCDefaults.ps1" Name="Create default Site Collection structure" />
<task Id="2" Script="SPO-FileMig.ps1" Name="Datacopy to SharePoint cloud" />
<task Id="3" Script="EXO-AddAdminDistri.ps1" Name="Exchange: Add admin user to distributiongroups" />
<task Id="4" Script="empty.ps1" Name="Todo..." />
</Application>
</Setting>
和脚本一样:
$Xml = [xml](Get-Content $ScriptPath\Settings.xml)
function Do-PromptTask
{
$task1 = $Xml.Setting.Application.task.name[0]
$task2 = $Xml.Setting.Application.task.name[1]
$task3 = $Xml.Setting.Application.task.name[2]
$task4 = $Xml.Setting.Application.task.name[3]
$task1_exec = $Xml.Setting.Application.task.script[0]
$task2_exec = $Xml.Setting.Application.task.script[1]
$task3_exec = $Xml.Setting.Application.task.script[2]
$task4_exec = $Xml.Setting.Application.task.script[3]
switch -wildcard (Prompt-SelectionList "Chose task to run:" @($task1,$task2,$task3,$task4))
{
$task1{$task_result = $task1_exec}
$task2{$task_result = $task2_exec}
$Task3{$task_result = $task3_exec}
$Task4{$task_result = $task4_exec}
""{Exit} #End Selection (cancel selected)
"*"{Do-PromptTask} #Keep prompting until "cancel" selected
}
Write-Host "$ScriptPath\Bin\$task_result"
}
Do-PromptTask
我认为应该更容易将其更改为:
function Do-PromptTask
{
switch -wildcard (Prompt-SelectionList "Chose task to run:" @($task['name'])) # Array of all names
{
foreach ($node in $Xml.Setting.Application.task) {
$task['name']{$task_result = $task_exec['script']}
}
""{Exit} #End Selection (cancel selected)
"*"{Do-PromptTask} #Keep prompting until "cancel" selected
}
Write-Host "$ScriptPath\Bin\$task_result"
}
Do-PromptTask
这可能吗?我也许正确的方式?我希望能够在XML中添加项目时动态生成表单中的列表
答案 0 :(得分:0)
我想我会完全避免使用switch
,并且这样做:
function Do-PromptTask
{
$sel = $null
while ($Xml.Setting.Application.task.name -notcontains $sel) {
$sel = Prompt-SelectionList "Chose task to run:" $Xml.Setting.Application.task.name
if ([String]::IsNullOrEmpty($sel)) {
exit
}
}
$task_result = & ($Xml.Setting.Application.task | Where-Object { $_.name -eq $sel } | Select-Object -ExpandProperty Script)
Write-Host "$ScriptPath\Bin\$task_result"
}
基本上利用XML的数组属性,从不引用单个索引。
答案 1 :(得分:0)
我不会使用Switch
,因为你希望它是动态的。我将哈希表与您的任务名称一起用作键,您的任务可以作为值块以scriptblocks的形式执行。像这样:
Do{
$AllTasks = @{}
$Xml.Setting.Application.task | ForEach{$AllTasks.add($_.Name,[scriptblock]::Create($_.Script))}
$Sel = Prompt-SelectionList "Chose task to run:" $AllTasks.Keys
If(!$Sel -match "Cancel"){$AllTasks[$Sel].Invoke()}
}While($Sel -notmatch "Cancel")
答案 2 :(得分:0)
我使用@TheMadTechnician中的代码找到答案,在执行表单的代码下面,并在路径中返回脚本名称。相当挑战,但它适用于XML并且是动态的。
$Xml = [xml](Get-Content $ScriptPath\Settings.xml)
. "$ScriptPath\Bin\O365-Functions.ps1"
$Sel = $null
Do {
$AllTasks = @{}
$Xml.Setting.Application.task | ForEach { $AllTasks.add($_.Name,[scriptblock]::Create($_.Script)) }
$Sel = Prompt-SelectionList "Chose task to run:" @($AllTasks.Keys)
$TaskResult = $ScriptPath+"\Bin\"+$AllTasks[$Sel].ToString()
Invoke-Expression "&'$TaskResult'"
} While( $Sel -notmatch $null )
感谢您的帮助!