Substitution failed while writing file

(imported topic written by SystemAdmin)

So, I’m attempting to create a task that executes a powershell script…

I pulled the code for the action from Daniel Heth at bigfix.me:

//

//PowerShell Script

//

//1. Save old ExecutionPolicy value

//

parameter “PolicyExisted”="{exists value “ExecutionPolicy” of key “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell” of (if exists x64 registry then x64 registry else registry)}"

parameter “oldExecutionPolicy”="{if (parameter “PolicyExisted” as boolean) then (value “ExecutionPolicy” of key “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell” of (if exists x64 registry then x64 registry else registry) as string) else “”}"

//

//2. set to ExecutionPolicy=Unrestricted and Pull PowerShell exe from registry… if 64bit then pull PowerShell x64

//

if {x64 of operating system}

regset64 "

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

" “ExecutionPolicy”=“Unrestricted”

parameter “PowerShellexe”="{value “Path” of key “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell” of x64 registry}"

else

//we need to determine what the current execution policy is so we can put it back when we’re done.

regset "

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

" “ExecutionPolicy”=“Unrestricted”

parameter “PowerShellexe”="{value “Path” of key “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell” of registry}"

endif

//

//3. Create PowerShell script and save to a ps1 file

//

delete createfile

delete fw.ps1

createfile until __END

param(

switch

$Local,

switch

$GPO

)

  1. If no switches are set the script will default to local firewall rules

if (!($Local) -and !($Gpo)) {

$Local = $true

}

$RegistryKeys = @()

if ($Local) {$RegistryKeys += ‘Registry::HKLM\System\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\FirewallRules’}

if ($GPO) {$RegistryKeys += ‘Registry::HKLM\Software\Policies\Microsoft\WindowsFirewall\FirewallRules’}

Foreach ($Key in $RegistryKeys) {

if (Test-Path -Path $Key) {

(Get-ItemProperty -Path $Key).PSObject.Members |

Where-Object {(@(‘PSPath’,‘PSParentPath’,‘PSChildName’) -notcontains $.Name) -and ($.MemberType -eq ‘NoteProperty’) -and ($_.TypeNameOfValue -eq ‘System.String’)} |

ForEach-Object {

Prepare hashtable

$HashProps = @{

NameOfRule = $_.Name

#RuleVersion = ($_.Value -split ‘|’)[0]

Action = $null

Active = $null

Dir = $null

#Protocol = $null

#LPort = $null

App = $null

Name = $null

#Desc = $null

#EmbedCtxt = $null

#Profile = $null

RA4 = $null

#RA6 = $null

#Svc = $null

#RPort = $null

#ICMP6 = $null

#Edge = $null

#LA4 = $null

#LA6 = $null

#ICMP4 = $null

#LPort2_10 = $null

#RPort2_10 = $null

}

Determine if this is a local or a group policy rule and display this in the hashtable

if ($Key -match ‘HKLM\System\CurrentControlSet’) {

$HashProps.RuleType = ‘Local’

} else {

$HashProps.RuleType = ‘GPO’

}

Iterate through the value of the registry key and fill PSObject with the relevant data

ForEach ($FireWallRule in ($_.Value -split ‘|’)) {

switch (($FireWallRule -split ‘=’)[0]) {

‘Action’ {$HashProps.Action = ($FireWallRule -split ‘=’)[1]}

‘Active’ {$HashProps.Active = ($FireWallRule -split ‘=’)[1]}

‘Dir’ {$HashProps.Dir = ($FireWallRule -split ‘=’)[1]}

#‘Protocol’ {$HashProps.Protocol = ($FireWallRule -split ‘=’)[1]}

#‘LPort’ {$HashProps.LPort = ($FireWallRule -split ‘=’)[1]}

‘App’ {$HashProps.App = ($FireWallRule -split ‘=’)[1]}

‘Name’ {$HashProps.Name = ($FireWallRule -split ‘=’)[1]}

#‘Desc’ {$HashProps.Desc = ($FireWallRule -split ‘=’)[1]}

#‘EmbedCtxt’ {$HashProps.EmbedCtxt = ($FireWallRule -split ‘=’)[1]}

#‘Profile’ {$HashProps.Profile = ($FireWallRule -split ‘=’)[1]}

‘RA4’ {

array

$HashProps.RA4 += ($FireWallRule -split ‘=’)[1]}

#‘RA6’ {

array

$HashProps.RA6 += ($FireWallRule -split ‘=’)[1]}

#‘Svc’ {$HashProps.Svc = ($FireWallRule -split ‘=’)[1]}

#‘RPort’ {$HashProps.RPort = ($FireWallRule -split ‘=’)[1]}

#‘ICMP6’ {$HashProps.ICMP6 = ($FireWallRule -split ‘=’)[1]}

#‘Edge’ {$HashProps.Edge = ($FireWallRule -split ‘=’)[1]}

#‘LA4’ {

array

$HashProps.LA4 += ($FireWallRule -split ‘=’)[1]}

#‘LA6’ {

array

$HashProps.LA6 += ($FireWallRule -split ‘=’)[1]}

#‘ICMP4’ {$HashProps.ICMP4 = ($FireWallRule -split ‘=’)[1]}

#‘LPort2_10’ {$HashProps.LPort2_10 = ($FireWallRule -split ‘=’)[1]}

#‘RPort2_10’ {$HashProps.RPort2_10 = ($FireWallRule -split ‘=’)[1]}

Default {}

}

}

Create and output object using the properties defined in the hashtable

New-Object -TypeName ‘PSCustomObject’ -Property $HashProps | Where-Object {$.Active -eq ‘TRUE’ -and $.Dir -eq ‘In’ -and $_.Action -eq ‘Allow’}

}

}

}

__END

move __createfile fw.ps1

//

//4. Execute PowerShell with ps1 script file

//

action uses wow64 redirection false

waithidden “{parameter “PowerShell.exe”}” -file “{pathname of client folder of current site}\fw.ps1 -GPO -Local | Format-Table -AutoSize -Wrap | Out-File C:\fw.log”

action uses wow64 redirection {x64 of operating system}

//

//5. Restore ExecutionPolicy back

//

if {x64 of operating system}

if {parameter “PolicyExisted” as boolean}

regset64 "

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

" “ExecutionPolicy”="{parameter “oldExecutionPolicy”}"

else

regdelete64 "

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

" “ExecutionPolicy”

endif

else

if {parameter “PolicyExisted” as boolean}

regset "

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

" “ExecutionPolicy”="{parameter “oldExecutionPolicy”}"

else

regdelete "

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

" “ExecutionPolicy”

endif

endif

//

//END OF SCRIPT

//

Anyway, I get a “Command failed (Substitution failed while writing file) createfile until __END” error when I run the action script through the fixlet debugger… Any ideas?

(imported comment written by SystemAdmin)

Ok, so I have figured out that I needed to escape the curly braces in the powershell script… but now I’m reaching a new fail point… My new error messages are:

Command failed (Relevance substitution failed) waithidden “{parameter “PowerShellexe”}” -file “{pathname of client folder of current site}\fw.ps1 -GPO -Local | Format-Table -AutoSize -Wrap | Out-File C:\fw.log”

Command failed (Relevance clauses must be surrounded by { and } guards.) waithidden “{parameter “PowerShellexe”}” -file “{pathname of client folder of current site}\fw.ps1 -GPO -Local | Format-Table -AutoSize -Wrap | Out-File C:\fw.log”

And the updated version of the script:

//

//PowerShell Script

//

//1. Save old ExecutionPolicy value

//

parameter “PolicyExisted”="{exists value “ExecutionPolicy” of key “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell” of (if exists x64 registry then x64 registry else registry)}"

parameter “oldExecutionPolicy”="{if (parameter “PolicyExisted” as boolean) then (value “ExecutionPolicy” of key “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell” of (if exists x64 registry then x64 registry else registry) as string) else “”}"

//

//2. set to ExecutionPolicy=Unrestricted and Pull PowerShell exe from registry… if 64bit then pull PowerShell x64

//

if {x64 of operating system}

regset64 “http://HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell” “ExecutionPolicy”=“Unrestricted”

parameter “PowerShellexe”="{value “Path” of key “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell” of x64 registry}"

else

//we need to determine what the current execution policy is so we can put it back when we’re done.

regset “http://HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell” “ExecutionPolicy”=“Unrestricted”

parameter “PowerShellexe”="{value “Path” of key “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell” of registry}"

endif

//

//3. Create PowerShell script and save to a ps1 file

//

delete createfile

delete fw.ps1

createfile until __END

param(

switch$Local,

switch$GPO

)

If no switches are set the script will default to local firewall rules

if (!($Local) -and !($Gpo)) {

$Local = $true

}

$RegistryKeys = @()

if ($Local) {{$RegistryKeys += ‘Registry::HKLM\System\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\FirewallRules’}

if ($GPO) {{$RegistryKeys += ‘Registry::HKLM\Software\Policies\Microsoft\WindowsFirewall\FirewallRules’}

Foreach ($Key in $RegistryKeys) {{

if (Test-Path -Path $Key) {{

(Get-ItemProperty -Path $Key).PSObject.Members |

Where-Object {{(@(‘PSPath’,‘PSParentPath’,‘PSChildName’) -notcontains $.Name) -and ($.MemberType -eq ‘NoteProperty’) -and ($_.TypeNameOfValue -eq ‘System.String’)} |

ForEach-Object {{

  1. Prepare hashtable

$HashProps = @{{

NameOfRule = $_.Name

#RuleVersion = ($_.Value -split ‘|’)[0]

Action = $null

Active = $null

Dir = $null

#Protocol = $null

#LPort = $null

App = $null

Name = $null

#Desc = $null

#EmbedCtxt = $null

#Profile = $null

RA4 = $null

#RA6 = $null

#Svc = $null

#RPort = $null

#ICMP6 = $null

#Edge = $null

#LA4 = $null

#LA6 = $null

#ICMP4 = $null

#LPort2_10 = $null

#RPort2_10 = $null

}

  1. Determine if this is a local or a group policy rule and display this in the hashtable

if ($Key -match ‘HKLM\System\CurrentControlSet’) {{

$HashProps.RuleType = ‘Local’

} else {{

$HashProps.RuleType = ‘GPO’

}

  1. Iterate through the value of the registry key and fill PSObject with the relevant data

ForEach ($FireWallRule in ($_.Value -split ‘|’)) {

switch (($FireWallRule -split ‘=’)[0]) {{

‘Action’ {{$HashProps.Action = ($FireWallRule -split ‘=’)[1]}

‘Active’ {{$HashProps.Active = ($FireWallRule -split ‘=’)[1]}

‘Dir’ {{$HashProps.Dir = ($FireWallRule -split ‘=’)[1]}

#‘Protocol’ {{$HashProps.Protocol = ($FireWallRule -split ‘=’)[1]}

#‘LPort’ {{$HashProps.LPort = ($FireWallRule -split ‘=’)[1]}

‘App’ {{$HashProps.App = ($FireWallRule -split ‘=’)[1]}

‘Name’ {{$HashProps.Name = ($FireWallRule -split ‘=’)[1]}

#‘Desc’ {{$HashProps.Desc = ($FireWallRule -split ‘=’)[1]}

#‘EmbedCtxt’ {{$HashProps.EmbedCtxt = ($FireWallRule -split ‘=’)[1]}

#‘Profile’ {{$HashProps.Profile = ($FireWallRule -split ‘=’)[1]}

‘RA4’ {{array$HashProps.RA4 += ($FireWallRule -split ‘=’)[1]}

#‘RA6’ {{array$HashProps.RA6 += ($FireWallRule -split ‘=’)[1]}

#‘Svc’ {{$HashProps.Svc = ($FireWallRule -split ‘=’)[1]}

#‘RPort’ {{$HashProps.RPort = ($FireWallRule -split ‘=’)[1]}

#‘ICMP6’ {{$HashProps.ICMP6 = ($FireWallRule -split ‘=’)[1]}

#‘Edge’ {{$HashProps.Edge = ($FireWallRule -split ‘=’)[1]}

#‘LA4’ {{array$HashProps.LA4 += ($FireWallRule -split ‘=’)[1]}

#‘LA6’ {{array$HashProps.LA6 += ($FireWallRule -split ‘=’)[1]}

#‘ICMP4’ {{$HashProps.ICMP4 = ($FireWallRule -split ‘=’)[1]}

#‘LPort2_10’ {{$HashProps.LPort2_10 = ($FireWallRule -split ‘=’)[1]}

#‘RPort2_10’ {{$HashProps.RPort2_10 = ($FireWallRule -split ‘=’)[1]}

Default {{}

}

}

  1. Create and output object using the properties defined in the hashtable

New-Object -TypeName ‘PSCustomObject’ -Property $HashProps | Where-Object {{$.Active -eq ‘TRUE’ -and $.Dir -eq ‘In’ -and $_.Action -eq ‘Allow’}

}

}

}

__END

move __createfile fw.ps1

//

//4. Execute PowerShell with ps1 script file

//

action uses wow64 redirection false

waithidden “{parameter “PowerShellexe”}” -file “{pathname of client folder of current site}\fw.ps1 -GPO -Local | Format-Table -AutoSize -Wrap | Out-File C:\fw.log”

action uses wow64 redirection {x64 of operating system}

//

//5. Restore ExecutionPolicy back

//

if {x64 of operating system}

if {parameter “PolicyExisted” as boolean}

regset64 “http://HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell” “ExecutionPolicy”="{parameter “oldExecutionPolicy”}"

else

regdelete64 “http://HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell” “ExecutionPolicy”

endif

else

if {parameter “PolicyExisted” as boolean}

regset “http://HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell” “ExecutionPolicy”="{parameter “oldExecutionPolicy”}"

else

regdelete “http://HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell” “ExecutionPolicy”

endif

endif

//

//END OF SCRIPT

//

So… any help is much appreciated…

(imported comment written by SystemAdmin)

Also, I suppose I should say that I had read earlier about properly escaping curly braces, but I didn’t think that would be necessary when using the “createfile until” relevance… I was thinking that “createfile until” would read in unformatted text without need to pay attention to BigFix relevance rules. Alas, I was wrong.

(imported comment written by SystemAdmin)

Are you still working in the debugger? It may be failing because the debugger won’t understand “current site” in your relevance.

http://www.ibm.com/developerworks/forums/thread.jspa?threadID=409150

(imported comment written by SystemAdmin)

Yes, I was working in the debugger… so that solved one problem. But, as one progresses, there are more questions…

Are there more escapeable characters? I’m looking at the script that was created on a machine, and it seems that square brackets ([]) weren’t included in the initial switch statements - which kind of fubar’d the script. It also looks like a few hashes (#) were left out… Which would also cause further problems…

(imported comment written by SystemAdmin)

I don’t know about the # or [ but occassionally it might not be interpreted correctly so you might have to use the hex character.

http://www.asciitable.com/

Here is an example:

http://www.ibm.com/developerworks/forums/thread.jspa?threadID=413080

Remember this is relevance so if you want it interpreted in an action script it has to be between curly braces {}.