How to create printf effect in PowerShell - powershell

How can I get my PowerShell script to print the info in tabular format as the script progresses.
In bash I would do this by
printf "%s\t%-15.15s" "Locale" "Jar"
if($verbose);then
printf "%-15.15s %-15.15s" "HelpSet" "Exception"
fi
printf "\t%s\n" "Status"
...
printf "%s\t%-15.15s" $locale $helpFileName
if($verbose); then
printf "%-15.15s %-15.15s" "$helpSetName" ${exclusion[$helpFileName]}
fi
status="OK"
...
if ($fixed); then
status="CORRECTED"
fi
printf "\t%s\n" $status
to get
Locale Jar HelpSet Exception Status
de help_D150 help_D150 CORRECTED
es help_D150 help_D150 OK
fr help_D150 help_D150 OK
it Locale folder not found
nl help_D150 help_D150 CORRECTED
Thanks

Try this out in your PowerShell console:
"{0}`t{1,-15}{2,-15}{3,-15}" -f "Locale", "Jar", "HelpSet", "Exception"
You can use string formatting quite easily from PowerShell.
The -f operator is a PowerShell short cut to the String.Format function, including all the standard and custom formatting .NET types support.

I have accepted Davids answer as that's what I asked for. However, I have chosen to create an object by
try{
add-type #'
namespace FFPS {
public class Data {
public string Locale;
public string JarFile;
public string HelpSet;
public string CorrectName;
public string Status;
}
}
'#
}
catch{}
and then use XML format file to format it as a table
<?xml version="1.0" encoding="utf-16"?>
<Configuration>
<ViewDefinitions>
<View>
<Name>ffps.data</Name>
<ViewSelectedBy>
<TypeName>ffps.data</TypeName>
</ViewSelectedBy>
<TableControl>
<TableHeaders>
<TableColumnHeader>
<Label>Locale</Label>
<Width>6</Width>
</TableColumnHeader>
<TableColumnHeader>
<Label>Jar File</Label>
<Width>16</Width>
</TableColumnHeader>
<TableColumnHeader>
<Label>Help Set</Label>
<Width>16</Width>
</TableColumnHeader>
<TableColumnHeader>
<Label>Correct Name</Label>
<Width>16</Width>
</TableColumnHeader>
<TableColumnHeader>
<Label>Status</Label>
<Width>100</Width>
</TableColumnHeader>
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<TableColumnItems>
<TableColumnItem>
<ScriptBlock>$_.Locale</ScriptBlock>
</TableColumnItem>
<TableColumnItem>
<ScriptBlock>$_.JarFile</ScriptBlock>
</TableColumnItem>
<TableColumnItem>
<ScriptBlock>$_.HelpSet</ScriptBlock>
</TableColumnItem>
<TableColumnItem>
<ScriptBlock>$_.CorrectName</ScriptBlock>
</TableColumnItem>
<TableColumnItem>
<ScriptBlock>$_.Status</ScriptBlock>
</TableColumnItem>
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
</TableControl>
</View>
</ViewDefinitions>
</Configuration>
and in the code do
$currentFile = New-Object ffps.data
$currentFile.Locale = "DE"
$currentFile.JarFile = "JarFile.Name"
...
$currentFile
to print the entries

Related

Usage of eclipse "org.eclipse.debug.ui.launchShortcuts"

I have implemented my custom shortcut.
It is working fine, when I execute it via context menu from project explorer or from the menu run launcher.
It is not working when I execute it via CTRL+F11, meant this command was called org.eclipse.debug.ui.commands.RunLast
As I debugged so far, this returns an empty list, which it should not.
org.eclipse.debug.internal.ui.launchConfigurations.LaunchShortcutExtension.getAssociatedConfigurationTypes():
public Set<String> getAssociatedConfigurationTypes() {
if(fAssociatedTypes == null) {
fAssociatedTypes = new HashSet<>();
IConfigurationElement[] children = fConfig.getChildren(IConfigurationElementConstants.CONFIGURATION_TYPES);
String id = null;
for (IConfigurationElement child : children) {
id = child.getAttribute(IConfigurationElementConstants.ID);
if(id != null) {
fAssociatedTypes.add(id);
}
}
}
return fAssociatedTypes;
}
<extension
point="org.eclipse.debug.ui.launchShortcuts">
<shortcut
class="com.my.LigthlyShortcut"
id="com.my.LigthlyShortcut"
label="Lightly Launch"
modes="run">
<contextualLaunch>
<enablement>
<with
variable="selection">
<count
value="1">
</count>
<iterate operator="and">
<adapt type="org.eclipse.core.resources.IFile">
<test property="org.eclipse.core.resources.extension"
value="lightly">
</test>
</adapt>
</iterate>
</with>
</enablement>
</contextualLaunch>
</shortcut>
</extension>
What am I missing?

Modify the Outlook CustomUI XML by powershell

friends. I want to check every of my company users' outlook customUI configuration file. Delete 2 UI buttons if any. I am trying to do it by powershell. But failed to do so. Any advice for my script?
Below is the XML content of olkexpplorer.officeUI. I need to check & delete the items in blockquotes in case they are existed in the configuration file.
<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>
Here is my script
$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”)
First of all, it is not clear how the ribbon XML looks like after running your code:
$input.save(“$path_to_office\new.officeUI”)
Anyway, you can do any modifications until the ribbon XML is loaded by the host application. At runtime, you may consider using callbacks where they are available and call the IRIbbonUI.Invalidate or IRibbonUI.InvalidateControl methods to get your custom UI invalidated and callbacks triggered. Here is what MSDN states:
For each of the callbacks the add-in implements, the responses are cached. For example, if an add-in writer implements the getImage callback procedure for a button, the function is called once, the image loads, and then if the image needs to be updated, the cached image is used instead of recalling the procedure. This process remains in-place until the add-in signals that the cached values are invalid by using the Invalidate method, at which time, the callback procedure is again called and the return response is cached. The add-in can then force an immediate update of the UI by calling the Refresh method.
The problem with your approach is that ChildNodes() only returns the immediate child nodes and not all child nodes (and using $input as a variable name is not considered a good practice anyway because its a reserved variable name).
So instead of ChildNodes() I would access the child node directly like so
$input.customUI.ribbon.tabs.tab.group | where-object { $DeleteNames -contains $_.id}
I would prefer the System.Xml.Linq classes like XDocument and XElement over the [xml] type alias because they make dealing with Xml inside a PowerShell script a little more convenient.
if this is the input 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>
'#
the following Powershell commands would remove all mso:control nodes with 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 has a Load() method for loading a xml file directly so there is no need to use the Parse() method (I was using for the sake of this example).
The only small drawback comparing to [xml] is that you have to consider namespaces.

Conditional on empty SelectNodes set

Given XML like this
<?xml version="1.0"?>
<Definitions>
<Products>
<Product_Group id="Revit">
<Product id="RVT2017">
<RSAccelerator>RSACCELERATOR2017</RSAccelerator>
<ShortcutPath os="6.0 6.1">C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Autodesk\Revit 2017</ShortcutPath>
<ShortcutPath os="6.2 6.3 10.0">C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Revit 2017</ShortcutPath>
</Product>
</Product_Group>
</Products>
</Definitions>
I want to test for the presence of the OS attribute so I can handle getting the value differently when there are two nodes differentiated by that attribute value vs no attribute at all.
I would have thought this would work, with appropriate values for the two variables.
if ($script:pxResources.SelectNodes("//Product[#id='$product']/$resource[#os]")) {
However, this is returning true even when no nodes are selected. I can use
if ($script:pxResources.SelectNodes("//Product[#id='$product']/$resource[#os]").count -gt 0) {
but that seems clumsy. Is there a better way to handle this, or is testing for an empty set the only option?
AFAIK you will always have to test as SelectNodes will return a System.Xml.XPathNodeList object, which PowerShell will consider to be true even if it is empty.
Agreed adding some code to test is not pretty but AFAIK it's necessary.
My preferred method is IsNullOrEmpty:
[String]::IsNullOrEmpty(<thing>)
# example
$exp = $script:pxResources.SelectNodes("//Product[#id='$product']/$resource[#os]")
if (-not [String]::IsNullOrEmpty($exp)) {# do something}
There's a;so the approach where you don't use XPath:
[xml]$xml = #"
<?xml version="1.0"?>
<Definitions>
<Products>
<Product_Group id="Revit">
<Product id="RVT2017">
<RSAccelerator>RSACCELERATOR2017</RSAccelerator>
<ShortcutPath os="6.0 6.1">C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Autodesk\Revit 2017</ShortcutPath>
<ShortcutPath os="6.2 6.3 10.0">C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Revit 2017</ShortcutPath>
<ShortcutPath os="">C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Anything\Revit 2017</ShortcutPath>
<ShortcutPath>C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Something\Revit 2017</ShortcutPath>
</Product>
</Product_Group>
</Products>
</Definitions>
"#
$product = "RVT2017"
$resource = "ShortcutPath"
($xml.Definitions.Products.Product_Group.Product | Where-Object { $_.id -eq $product }).$resource | ForEach-Object {
if ($null -eq $_.os) {
Write-Host "'os' attribute missing on $_"
}
elseif ([string]::IsNullOrWhiteSpace($_.os)) {
Write-Host "'os' attribute empty on element $($_.outerXml)"
}
else {
Write-Host "'os' = $($_.os) on element $($_.outerXml)"
}
}
This will output
'os' = 6.0 6.1 on element <ShortcutPath os="6.0 6.1">C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Autodesk\Revit 2017</ShortcutPath>
'os' = 6.2 6.3 10.0 on element <ShortcutPath os="6.2 6.3 10.0">C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Revit 2017</ShortcutPath>
'os' attribute empty on element <ShortcutPath os="">C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Anything\Revit 2017</ShortcutPath>
'os' attribute missing on C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Something\Revit 2017

web.config changes for KB3159706

i spent a few hours trying to code this by myself, but i don't know much about editing the web.config and all the examples i found don't come close to what i need. CHANGE#1 is unique because it does include the typical key=value.
I want to be able to script (PowerShell) the required modifications of Web.Config, only if the values do not already exist.
CHANGE#1:
Onsert this
(if not already there and "true"): multipleSiteBindingsEnabled="true"
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
CHANGE#2:
Insert this if not already there:
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="SSL"
contract="Microsoft.UpdateServices.Internal.IClientWebService" />
<endpoint address="secured"
binding="basicHttpBinding"
bindingConfiguration="SSL"
contract="Microsoft.UpdateServices.Internal.IClientWebService" />
It goes between here:
<services>
<service
name="Microsoft.UpdateServices.Internal.Client"
behaviorConfiguration="ClientWebServiceBehaviour">
<!-- ... CODE FROM CHANGE#2 GOES HERE ... -->
</service>
</services>
This is the code so far for change#1 (not working):
$sWSUSwebConfig = "C:\Program Files\Update Services\WebServices\ClientWebService\Web.Config"
$xFileContent = [Xml](Get-Content $sWSUSwebConfig)
$root = $xFileContent.get_DocumentElement()
foreach ($item in $root."system.serviceModel"."serviceHostingEnvironment") {
if ($item."multipleSiteBindingsEnabled" -ine "true") {
$activeConnection = $root.serviceHostingEnvironment
$activeConnection.SetAttribute("multipleSiteBindingsEnabled", "true")
#$item.add."multipleSiteBindingsEnabled" = "true"
$iKeyFound = $true
}
}
$xFileContent.Save("c:\temp\web.config")
Reference for modifications: step 3 from kb3159706.

Mule configuration file xsd not valid in Eclipse

I am publishing Web Services using Mule. Everything works fine but I do not understand why my mule configuration file is not valid in Eclipse.
This is the error message displayed by Eclipse:
cvc-complex-type.2.4.a: Invalid content was found starting with element 'cxf:simple-service'. One of '{"http://www.mulesoft.org/schema/mule/core":annotations, "http://www.mulesoft.org/schema/mule/core":abstract-transformer, "http://www.mulesoft.org/schema/mule/core":abstract-filter, "http://www.mulesoft.org/schema/mule/core":abstract-security-filter, "http://www.mulesoft.org/schema/mule/core":abstract-intercepting-message-processor, "http://www.mulesoft.org/schema/mule/core":abstract-observer-message-processor, "http://www.mulesoft.org/schema/mule/core":processor, "http://www.mulesoft.org/schema/mule/core":custom-processor, "http://www.mulesoft.org/schema/mule/core":abstract-mixed-content-message-processor, "http://www.mulesoft.org/schema/mule/core":response, "http://www.mulesoft.org/schema/mule/core":abstract-redelivery-policy, "http://www.mulesoft.org/schema/mule/core":abstract-transaction, "http://www.mulesoft.org/schema/mule/core":abstract-reconnection-strategy, "http://www.mulesoft.org/schema/mule/core":abstract-multi-transaction, "http://www.mulesoft.org/schema/mule/core":property, "http://www.mulesoft.org/schema/mule/core":properties}' is expected. mule-components.xml /my-project/src/main/resources line 35 XML Problem
This is the portion of my configuration file at line 35:
<flow name="MonFlow">
<inbound-endpoint address="servlet://monService">
<cxf:simple-service
serviceClass="mon.package.MonClassService" />
</inbound-endpoint>
<component>
<spring-object bean="myApp.monClassService" />
</component>
</flow>
Here are the schemas used in the file:
<mule xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:file="http://www.mulesoft.org/schema/mule/file"
xmlns:http="http://www.mulesoft.org/schema/mule/http"
xmlns:https="http://www.mulesoft.org/schema/mule/https"
xmlns:jetty="http://www.mulesoft.org/schema/mule/jetty"
xmlns:jetty-ssl="http://www.mulesoft.org/schema/mule/jetty-ssl"
xmlns:stdio="http://www.mulesoft.org/schema/mule/stdio"
xmlns:vm="http://www.mulesoft.org/schema/mule/vm"
xmlns:mulexml="http://www.mulesoft.org/schema/mule/xml"
xmlns:cxf="http://www.mulesoft.org/schema/mule/cxf"
xmlns:servlet="http://www.mulesoft.org/schema/mule/servlet"
xmlns:spring="http://www.springframework.org/schema/beans"
xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/core
http://www.mulesoft.org/schema/mule/core/3.2/mule.xsd
http://www.mulesoft.org/schema/mule/file
http://www.mulesoft.org/schema/mule/file/3.2/mule-file.xsd
http://www.mulesoft.org/schema/mule/http
http://www.mulesoft.org/schema/mule/http/3.2/mule-http.xsd
http://www.mulesoft.org/schema/mule/https
http://www.mulesoft.org/schema/mule/https/3.2/mule-https.xsd
http://www.mulesoft.org/schema/mule/jetty
http://www.mulesoft.org/schema/mule/jetty/3.2/mule-jetty.xsd
http://www.mulesoft.org/schema/mule/jetty-ssl
http://www.mulesoft.org/schema/mule/jetty-ssl/3.2/mule-jetty-ssl.xsd
http://www.mulesoft.org/schema/mule/stdio
http://www.mulesoft.org/schema/mule/stdio/3.2/mule-stdio.xsd
http://www.mulesoft.org/schema/mule/vm
http://www.mulesoft.org/schema/mule/vm/3.2/mule-vm.xsd
http://www.mulesoft.org/schema/mule/xml
http://www.mulesoft.org/schema/mule/xml/3.2/mule-xml.xsd
http://www.mulesoft.org/schema/mule/cxf
http://www.mulesoft.org/schema/mule/cxf/3.2/mule-cxf.xsd
http://www.mulesoft.org/schema/mule/servlet
http://www.mulesoft.org/schema/mule/servlet/3.2/mule-servlet.xsd
">
Any ideas?
Thank you!
Tu dis "dans Eclipse", donc j'assume que tu n'es pas dans "Mule Studio".
Il te faut ajouter les schemas qui se trouvent dans chaque JAR de Mule dans le dictionnaire XML d'Eclipse: http://genschawtech.blogspot.ca/2008/09/eclipse-xml-catalog-entry-for-dtd-or.html
Tu as peut-être aussi ce probleme: http://blogs.mulesoft.org/overcoming-xml-validation-errors-in-eclipse-35/