Using powershell in fixlets with embedded bigfix code

written by SystemAdmin)

I’m attempting to search and replace the word HOSTNAME and replace it with {hostname as uppercase} in a template file downloaded to each endpoint using a powershell script. In the example below, this fails on the line containing {hostname as uppercase}. Looking for suggestions on other ways to accomplish this or do I just have syntax wrong?

createfile until __EOF

Get-Content “D:\Apps\Cybermation\ESP System Agent R7\agentparm.new”) |

Foreach-Object {$_ -replace “HOSTNAME”, “{hostname as uppercase}”} |

Set-Content “D:\Apps\Cybermation\ESP System Agent R7\agentparm.txt”

__EOF

move __createfile “D:\Apps\Cybermation\ESP System Agent R7\updatehost.ps1”

rundetached “C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe &D:\Apps\Cybermation\ESP System Agent R7\updatehost.ps1”

(imported comment written by SystemAdmin)

I beleive the problem is that bigfix is trying to interpet the outer { } around the command as they turn pink in the editor

Foreach-Object {$_ -replace “HOSTNAME”, “{hostname as uppercase}”} |

(imported comment written by SystemAdmin)

That’s correct! If you don’t want the curly braces treated as a special character (e.g. Relevance substitution) you will ha to escape it. You can do that by doubling up on only the first one. For instance:

Createfile until …

{hostname as uppercase}

Will evaluate the relevance

Createfile until …

{{hostname as uppercase}

Will not evaluate the relevance.

(imported comment written by SystemAdmin)

Foreach-Object {$_ -replace “HOSTNAME”, “{hostname as uppercase}”} |

I DO want the {hostname as uppercase} to evaluate, but not the {$_ and } | at the end

It’s failing because everything inside of the outer set of {} turns pink in the editor and failes when it’s run

(imported comment written by SystemAdmin)

Ahh… Here are a couple other ways to escape it based on your use case:

https://www.ibm.com/developerworks/forums/thread.jspa?messageID=14750659&#14750659

(imported comment written by SystemAdmin)

Almost, but that’s opposite of what I need. I need the internal {} to evaluate and the outer to not…

(imported comment written by SystemAdmin)

Does it not work if you use %7B and %7D instead of {} for the ones you don’t want interpreted?

(imported comment written by SystemAdmin)

So something like:

Foreach-Object %7B$_ -replace “HOSTNAME”, “{hostname as uppercase}”%7D |

(imported comment written by SystemAdmin)

Another, maybe not so elegant, way to do this might be to build the whole line in relevance inside the curly braces:

q: {“Foreach-Object %7B$_ -replace %22HOSTNAME%22, %22” & (hostname as uppercase) & “%22%7D |”}

A: Foreach-Object {$_ -replace “HOSTNAME”, “WIN-SMD2P7N3F49”} |

T: 2.198 ms

I: singular string

(imported comment written by SystemAdmin)

That worked to create the updatehost.ps1,

(Get-Content “D:\Apps\Cybermation\ESP System Agent R7\agentparm.new”) |

Foreach-Object {$_ -replace “HOSTNAME”, “WSPRD304”} |

Set-Content “D:\Apps\Cybermation\ESP System Agent R7\agentparm.txt”

But the command to run powershell against the file says it completes, but never produces results.

I don’t think it executed the powershell command.

createfile until __EOF

(Get-Content “D:\Apps\Cybermation\ESP System Agent R7\agentparm.new”) |

{“Foreach-Object %7B$_ -replace %22HOSTNAME%22, %22” & (hostname as uppercase) & “%22%7D |”}

Set-Content “D:\Apps\Cybermation\ESP System Agent R7\agentparm.txt”

__EOF

copy __createfile “D:\Apps\Cybermation\ESP System Agent R7\updatehost.ps1”

waithidden cmd.exe /C “C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe ‘D:\Apps\Cybermation\ESP System Agent R7\updatehost.ps1’”

(imported comment written by SystemAdmin)

Forgot about that part… I just went through this a a couple weeks ago. It is an issue with 64/32 bit systems. You have to set powershell to unrestricted in both. And this is where you run into problems on 64bit machines. Here is a little more info for your reading pleasure:

http://www.paessler.com/knowledgebase/en/topic/7773-powershell-script-works-from-powershell-prompt-but-not-from-prtg

You have to enable unrestricted in both 32 bit (powershell.exe) and 64 bit (C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe)

Here is an example I set up recently.

//Set to Unrestricted

//32 bit

if {name of operating system as lowercase contains “win” and architecture of operating system = “x86”}

wait cmd.exe /C powershell.exe -noninteractive -Command Set-Execution Policy “Unristricted”

//64bit

else

wait cmd.exe /C C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -noninteractive -Command Set-Execution Policy “Unristricted”

endif

//delete files if pre existing

delete “c:\test.txt”

delete “c:\test.ps1”

createfile until __EOF

Get-WmiObject -Class Win32_OperatingSystem -Namespace root/cimv2 -ComputerName . | Format-Table -Property TotalVirtualMemorySize,TotalVisibleMemorySize,FreePhysicalMemory,FreeVirtualMemory,FreeSpaceInPagingFiles

__EOF

move __createfile c:\test.ps1

if {name of operating system as lowercase contains “win” and architecture of operating system = “x86”}

wait cmd.exe /C powershell.exe c:\test.ps1 >> c:\test.txt

else

wait cmd.exe /C C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe c:\test.ps1 >> c:\test.txt

endif

(imported comment written by SystemAdmin)

Sounds interesting, but even with running

powershell.exe D:\Apps\tmp\updatehost.ps1

it fails to execute from within bigfix. Command line it works just fine.

I tried those commands you suggest, but get errors setting them

The term ‘Set-Execution’ is not recognized as the name of a cmdlet, fuction, script…

(imported comment written by SystemAdmin)

This sounds exactly like the issue I had. I am no powershell expert but I muddled my way through once I realized there were 2 different powershells and that the ExecutionPolicy had to be set to unrestricted.

More details:

Try running the following commands at the command line:

c:>%SystemRoot%\syswow64\WindowsPowerShell\v1.0\powershell.exe

PS c:>Get-ExecutionPolicy

C:>%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe

PS c:>Get-ExecutionPolicy

I originally only had the 32 bit version set to unrestricted. That was why I added the piece that was capturing the “c:\test.txt” so I could see what the output from running the ps1 was.

(imported comment written by SystemAdmin)

Jeff,

Sorry for fumbling through this… It is all coming back slowly.

Of course the first part of the script as I have it above won’t work. You can’t script powershell until you change it from the default “restricted”. And I was trying to script it to change it… The Execution policy can simply be changed in the registry. I just tested this one against a x64 server. See if this helps:

//Set to Unrestricted

//32 bit

if {name of operating system as lowercase contains “win” and architecture of operating system = “x86”}

regset "

http://HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell

" “ExecutionPolicy”=“Unrestricted”

//64bit

else

regset "

http://HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell

" “ExecutionPolicy”=“Unrestricted”

endif

//delete files if pre existing

delete “c:\test.txt”

delete “c:\test.ps1”

createfile until __EOF

Get-WmiObject -Class Win32_OperatingSystem -Namespace root/cimv2 -ComputerName . | Format-Table -Property TotalVirtualMemorySize,TotalVisibleMemorySize,FreePhysicalMemory,FreeVirtualMemory,FreeSpaceInPagingFiles

__EOF

move __createfile c:\test.ps1

if {name of operating system as lowercase contains “win” and architecture of operating system = “x86”}

wait cmd.exe /C powershell.exe c:\test.ps1 >> c:\test.txt

else

wait cmd.exe /C C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe c:\test.ps1 >> c:\test.txt

endif

(imported comment written by SystemAdmin)

You are correct about the restricted mode. I’ve built a PowerShell template fixlet last year and you might find it helpful to compare.

http://bigfix.me/cdb/search/powershell

(imported comment written by MattBoyd)

Wowzers. Any reason it can’t or shouldn’t be done with PowerShell’s -ExecutionPolicy parameter? That seems like an easier way to change the policy temporarily…

waithidden powershell.exe -ExecutionPolicy Unrestricted YourPSFile.psl