Измените Outlook CustomUI XML с помощью powershell - PullRequest
0 голосов
/ 28 мая 2020

друзей. Я хочу проверить файл конфигурации customUI для каждого пользователя моей компании. Удалите 2 кнопки пользовательского интерфейса, если они есть. Я пытаюсь сделать это с помощью PowerShell. Но сделать этого не удалось. Есть какие-нибудь советы по поводу моего сценария?

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

<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”)

Ответы [ 2 ]

0 голосов
/ 28 мая 2020

Проблема с вашим подходом заключается в том, что ChildNodes() возвращает только непосредственные дочерние узлы, а не все дочерние узлы (и использование $ input в качестве имени переменной в любом случае не считается хорошей практикой, поскольку это зарезервированное имя переменной).

Таким образом, вместо ChildNodes() я бы получил доступ к дочернему узлу напрямую, например, так

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

Я бы предпочел System.Xml.Linq классы, такие как XDocument и XElement поверх псевдонима типа [xml], потому что они делают работу с Xml внутри сценария PowerShell немного более удобным.

если это вход 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 удалят все mso: control узлы с visible="false":

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] заключается в том, что вы должны учитывать имя пробелы.

0 голосов
/ 28 мая 2020

Прежде всего, непонятно, как будет выглядеть лента XML после запуска вашего кода:

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

В любом случае, вы можете вносить любые изменения, пока лента XML не будет загружена хост-приложение. Во время выполнения вы можете рассмотреть возможность использования обратных вызовов там, где они доступны, и вызвать методы IRIbbonUI.Invalidate или IRibbonUI.InvalidateControl, чтобы сделать ваш пользовательский интерфейс недействительным и запустить обратные вызовы. Вот что сообщает MSDN:

Для каждого обратного вызова, реализуемого надстройкой, ответы кэшируются. Например, если средство записи надстройки реализует процедуру обратного вызова getImage для кнопки, функция вызывается один раз, загружается изображение, а затем, если изображение необходимо обновить, вместо вызова процедуры используется кэшированное изображение. Этот процесс остается на месте до тех пор, пока надстройка не сообщит, что кэшированные значения недействительны, с помощью метода Invalidate, после чего снова вызывается процедура обратного вызова и кэшируется ответ на возврат. Затем надстройка может принудительно выполнить немедленное обновление пользовательского интерфейса, вызвав метод Refre sh.

...