【问题标题】:Modify the Outlook CustomUI XML by powershell通过 powershell 修改 Outlook CustomUI XML
【发布时间】:2020-05-28 09:32:58
【问题描述】:

朋友。我想检查我公司每个用户的 Outlook customUI 配置文件。删除 2 个 UI 按钮(如果有)。我正在尝试通过powershell来做到这一点。但未能如愿。对我的脚本有什么建议吗?

以下是 olkexplorer.officeUI 的 XML 内容。我需要检查并删除块引用中的项目,以防它们存在于配置文件中。

<mso:customUI xmlns:x1="Microsoft.Forefront.SpamReporterAddin.Connect" xmlns:mso="http://schemas.microsoft.com/office/2009/07/customui">
  <mso:ribbon>
    <mso:qat />
    <mso:tabs>
      <mso:tab idQ="mso:TabMail">
      <mso:group id="mso_c1.45620CF" label="Phishing Report" imageMso="TrustCenter" autoScale="true" 
      <mso:control idQ="x1:ExplorerPhishReportMenuButton" imageMso="TrustCenter" visible="true"/> 
      </mso:group>


>     <mso:group id="mso_c2.14817EBA" label="Junk" autoScale="true">
>        <mso:control idQ="x1:ExplorerSpamReportMenuButton" visible="true" />
>        <mso:control idQ="x1:ExplorerPhishReportMenuButton" imageMso="GreenBall" visible="true" />
>     </mso:group>

      </mso:tab>
    </mso:tabs>
  </mso:ribbon>
</mso:customUI>

这是我的脚本

$input = [xml](Get-Content -Path “$path_to_office\olkexplorer.officeUI”)
$deletenames="mso_c2.14817EBA" 
($input.customUI.ChildNodes |Where-object { $deletenames -contains $_.Name}) | ForEach- 
   Object{[void]$_.ParentNode.RemoveChild($_)} 
$input.save(“$path_to_office\new.officeUI”)

【问题讨论】:

  • 你的代码的输出是什么?

标签: powershell outlook ribbonx


【解决方案1】:

首先,不清楚运行代码后功能区 XML 的样子:

$input.save(“$path_to_office\new.officeUI”)

无论如何,在主机应用程序加载功能区 XML 之前,您可以进行任何修改。在运行时,您可以考虑使用可用的回调并调用IRIbbonUI.InvalidateIRibbonUI.InvalidateControl 方法来使您的自定义UI 无效并触发回调。以下是 MSDN 的声明:

对于插件实现的每个回调,响应都会被缓存。例如,如果加载项编写器为按钮实现 getImage 回调过程,则调用该函数一次,加载图像,然后如果需要更新图像,则使用缓存的图像而不是调用过程。此过程保持原位,直到加载项使用 Invalidate 方法发出缓存值无效的信号,此时,再次调用回调过程并缓存返回响应。然后,插件可以通过调用 Refresh 方法强制立即更新 UI。

【讨论】:

    【解决方案2】:

    您的方法的问题在于 ChildNodes() 仅返回直接子节点而不是所有子节点(并且使用 $input 作为变量名无论如何都不是一种好的做法,因为它是保留的变量名)。

    所以我会像这样直接访问子节点,而不是 ChildNodes()

    $input.customUI.ribbon.tabs.tab.group | where-object { $DeleteNames -contains $_.id}
    

    比起 [xml] 类型别名,我更喜欢 System.Xml.Linq 类,例如 XDocumentXElement因为它们使在 PowerShell 脚本中处理 Xml 更加方便。

    如果这是输入 xml:

    $XmlCode = @'
     <mso:customUI xmlns:mso="http://schemas.microsoft.com/office/2009/07/customui">
      <mso:ribbon>
       <mso:qat><mso:sharedControls>
        <mso:control idQ="mso:FileNewDefault" visible="false"/>
        <mso:control idQ="mso:FileOpen" visible="false"/>
        <mso:control idQ="mso:FileSave" visible="true"/>
        <mso:control idQ="mso:FileSendAsAttachment" visible="false"/>
         <mso:control idQ="mso:FilePrintQuick" visible="false"/>
         <mso:control idQ="mso:SpellingAndGrammar" visible="false" 
          insertBeforeQ="mso:PrintPreviewAndPrint"/>
         <mso:control idQ="mso:Undo" visible="true" 
          insertBeforeQ="mso:PrintPreviewAndPrint"/>
         <mso:control idQ="mso:RedoOrRepeat" visible="true" 
          insertBeforeQ="mso:PrintPreviewAndPrint"/>
         <mso:control idQ="mso:TableDrawTable" visible="false" 
          insertBeforeQ="mso:PrintPreviewAndPrint"/>
         <mso:control idQ="mso:FileOpenRecentFile" visible="false" 
          insertBeforeQ="mso:PrintPreviewAndPrint"/>
         <mso:control idQ="mso:FontDialog" visible="true" 
          insertBeforeQ="mso:PrintPreviewAndPrint"/>
         <mso:control idQ="mso:FontSizeDecreaseWord" visible="true" 
          insertBeforeQ="mso:PrintPreviewAndPrint"/>
         <mso:control idQ="mso:FontSize" visible="true" 
          insertBeforeQ="mso:PrintPreviewAndPrint"/>
         <mso:control idQ="mso:PageSetupDialog" visible="true" 
          insertBeforeQ="mso:PrintPreviewAndPrint"/>
         <mso:control idQ="mso:PrintPreviewAndPrint" visible="true"/>
        </mso:sharedControls>
       </mso:qat>
      </mso:ribbon>
     </mso:customUI>
    '@
    

    以下 Powershell 命令将删除所有带有visible="false"mso:control 节点:

    using namespace System.Xml.Linq
    
    Add-Type -Assembly System.Xml.Linq
    
    $xmlCode = "<<as shown above>>"
    
    $xRoot = [XDocument]::Parse($xmlCode)
    $msoNs = [XNamespace]::get("http://schemas.microsoft.com/office/2009/07/customui")
    $DeleteNodes = $xRoot.Descendants($msoNs + "control").where{$_.Attribute("visible").Value -eq "false"}
    $DeleteNodes.ForEach{$_.Remove()}
    $xRoot.ToString()
    
    # Save the new xml
    $XmlPath = [System.IO.Path]::GetTempFileName()
    $xRoot.Save($XmlPath)
    

    XDocument 有一个 Load() 方法可以直接加载一个 xml 文件,所以不需要使用 Parse() 方法(我是为了这个例子而使用的)。

    [xml] 相比,唯一的小缺点是您必须考虑命名空间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多