Word Automation and Font Shading

I am not sure if this is the right place to ask but I have to start somewhere. I am writing a PowerShell script which will create a Word 2019 document with some information gleaned from a Nessus scan. If successful I will probably use it in other places as well. I’ve made progress but have found something that doesn’t work. I suspect it may be a bug elsewhere (e.g. Word or .Net etc.). However, I thought I better start at the beginning. The basic code is:

$Selection = $Report.Parent.Selection
$Selection.Font.Shading.Texture = [Microsoft.Office.Interop.Word.Shading]::wdTextureDarkHorizontal
$Selection.Font.Shading.ForegroundPatternColor = [Microsoft.Office.Interop.Word.WdColor]::wdColorRed
$Selection.Font.Shading.BackgroundPatternColor = [Microsoft.Office.Interop.Word.WdColor]::wdColorLightBlue
Add-Text -Document $Report -Text "This should be shaded text 

That produces shaded text right enough but just in plain blue. It does not do create the texture. If I move the line that sets the backgroundpatterncolor so that it is before the line that sets the texture then there is no shading whatsoever. It seems that the texture and foregroundpatterncolor not only don’t work but they stop the backgroundpatterncolor line working as well.

Part of my attempt to fix this involves running word, creating a line of text and then recording a macro that creates a textured shading. The macro is:

Sub Macro1()
    With Selection.Font
        With .Shading
            .Texture = wdTextureDarkHorizontal
            .ForegroundPatternColor = wdColorRed
            .BackgroundPatternColor = 5287936
        End With
        .Borders(1).LineStyle = wdLineStyleNone
        .Borders.Shadow = False
    End With
    With Options
        .DefaultBorderLineStyle = wdLineStyleSingle
        .DefaultBorderLineWidth = wdLineWidth050pt
        .DefaultBorderColor = wdColorAutomatic
    End With
End Sub

and I have replicated it in PowerShell as:

$Selection = $Report.Parent.Selection
$Selection.Font.Shading.Texture = [Microsoft.Office.Interop.Word.Shading]::wdTextureDarkHorizontal
$Selection.Font.Shading.ForegroundPatternColor = [Microsoft.Office.Interop.Word.WdColor]::wdColorRed
$Selection.Font.Shading.BackgroundPatternColor = 5287936
$Selection.Font.Borders(1).LineStyle = [Microsoft.Office.Interop.Word.WdLineStyle]::wdLineStyleNone
$Selection.Font.Borders.Shadow = $FALSE
$Selection.Application.Options.DefaultBorderLineStyle = [Microsoft.Office.Interop.Word.WdLineStyle]::wdLineStyleSingle
$Selection.Application.Options.DefaultBorderLineWidth = [Microsoft.Office.Interop.Word.WdLineWidth]::wdLineWidth050pt
$Selection.Application.Options.DefaultBorderColor = [Microsoft.Office.Interop.Word.WdColor]::wdColorAutomatic

and that also fails. If I run the VB macro though, it works and produces the textured shading that I specified. On the other hand, it fails when PowerShell executes the same instructions. I suspect it is a .net or Word problem but I am not sure since it does work in VB.

Any thoughts will be appreciated.

Texture is expecting a number, representing the index of the texture (I think):

Texture Property WdTextureIndex Texture () {get} {set}

It works if you specify an integer between 0 and 1000.

Hi Matt,
Thanks for the reply. You are right the textures are represented as integers and as it happened I had got it wrong. The line:

$Selection.Font.Shading.Texture = [Microsoft.Office.Interop.Word.Shading]::wdTextureDarkHorizontal

should actually have been

$Selection.Font.Shading.Texture = [Microsoft.Office.Interop.Word.WdTextureIndex]::wdTextureDarkHorizontal

Substituting -1 for [Microsoft.Office.Interop.Word.Shading]::wdTextureDarkHorizontal
made no difference. I think it is a bug either in Word or .Net either in documentation or code because I would expect this

$Selection.Font.Shading.Texture = [Microsoft.Office.Interop.Word.WdTextureIndex]::wdTextureDarkHorizontal
write-host ">>> " $Selection.Font.Shading.Texture

to print -1 or whatever value I assign to $Selection.Font.Shading.Texture but, no matter what value I assign to that, the write-host always display 0 and it turns out the same is true for $Selection.Font.Shading.ForegroundPatternColor. Oddly enough, if you assign an invalid integer to any of them they report errors but the Texture one ignores valid values.

Another odd thing is that it seems to only accept the value set last. So, in the examples above I have set the values in the order texture, foreground, background and that results in a solid blue shading. If I do it in the order foreground, background, texture then I get the texture but in black and white. I get the same results with background, foreground, texture. However, background, texture, foreground does nothing at all and foreground, texture, background gives plain blue shading. Maybe there is some other step that has to be done that either I have missed or is undocumented and perhaps it is just a good old bug. I have found quite a few bugs during this exercise so maybe this is just another one to add to the collection.

Thanks for your suggestion anyway.

Best wishes…
Colin

Sorry to reply to my own post but I have a bit more information. if I change the code from

$Selection.Font.Shading..........

to

$Selection.ParagraphFormat.Shading.........

in each of the lines then it works as expected. This is fine if a whole paragraph of text needs to be shaded but not so useful if it is just a couple of words.

Best wishes…
Colin

You could have edited your post. :point_up_2:t4: :wink:

$Selection.Font.Shading.Texture = [Microsoft.Office.Interop.Word.WdTextureIndex]::wdTextureDarkHorizontal

That worked for me too.

I suspect it may be the way you’re getting $Selection. For your code to work for me as it is, the document has to be visible and I have to make the selection which is obviously no good for automation.

To make the selection in code, you can do something like this which gets just the first word:

$Selection = $document.Words(1)

Hi Matt,

In the early hours of the morning I finally gave up on the approach I am using and tried it a different way and that seems to be far more successful. I am constructing the document on the fly and building a library of PowerShell functions to do it. You can probably imagine the sort of thing. Functions like Open-Document, Close-Document, Add-Text, Set-FontColour etc etc. I’ve done all the font ones and most of the paragraph ones (e.g. Set-ParagraphLeftIndent etc.) I use long names but I also have a short form such as /PL[10] for the setting the left indent. Although it isn’t obvious from the names there is a start and end to each command. What I do is use the selection point at the start and the selection point at the end to start and end whatever formatting I am doing. That works for all the font settings and works for the paragraph settings except shading which is why I find it so strange. I also found that if I do something like


$Selection.Font.Shading.Texture = [Microsoft.Office.Interop.Word.WdTextureIndex]::wdTextureDarkHorizontal


Write-host $([int] $Selection.Font.Shading.Texture)