Hello,
Due to issue of File resource adding BOM header to contents of text files being written I have to resort to writing Script resource to curcumvent it. Unfortunately none of variables inside script are being expanded when MOF is compiled (unlike File resource which does). Is it possible to compile MOF file with variables intact or what would be the solution to write out string passed during compilation to file system when DSC is invoked?
Configuration SwarmManager
{
# Parameter help description
param
(
[Parameter(Mandatory)]
[string] $privateKey
)
Node localhost
{
File MyFile {
Contents = $privateKey
DestinationPath = "$env:HOMEPATH\fromFile.txt"
}
Script MyScript {
SetScript = {
$privateKey | out-file -FilePath "$env:HOMEPATH\FromScript.txt" -Encoding ascii -Verbose
}
TestScript = {
(Test-Path -Path "$env:HOMEPATH\FromScript.txt")
}
GetScript = { @{CertFiles = (Test-Path "C:\ProgramData\docker\certs.d\ca.cer" )}
}
}
}
}
SwarmManager -Verbose
Mof file contents are below
instance of MSFT_FileDirectoryConfiguration as $MSFT_FileDirectoryConfiguration1ref
{
ResourceID = "[File]MyFile";
Contents = "abc";
DestinationPath = "\\Users\\gsuvalia\\fromFile.txt";
ModuleName = "PSDesiredStateConfiguration";
SourceInfo = "D:\\test\\dsctest.ps1::13::9::File";
ModuleVersion = "1.0";
ConfigurationName = "SwarmManager";
};
instance of MSFT_ScriptResource as $MSFT_ScriptResource1ref
{
ResourceID = "[Script]MyScript";
GetScript = " @{CertFiles = (Test-Path \"C:\\ProgramData\\docker\\certs.d\\ca.cer\" )} \n ";
TestScript = " \n (Test-Path -Path \"$env:HOMEPATH\\FromScript.txt\") \n \n ";
SourceInfo = "D:\\test\\dsctest.ps1::18::9::Script";
SetScript = "\n $privateKey | out-file -FilePath \"$env:HOMEPATH\\FromScript.txt\" -Encoding ascii -Verbose\n \n ";
ModuleName = "PsDesiredStateConfiguration";
jnury
February 26, 2018, 2:10am
2
Hi,
You may try to build your scriptblocks based on a string:
SetScript = [Scriptblock]::Create("'$privateKey' | out-file -FilePath '$env:HOMEPATH\FromScript.txt' -Encoding ascii -Verbose")
Also, you are 90% of the way to creating a new resource. I would consider doing that instead of using the Script resource.
Scriptblock did not do it either, still appears as variable in final MOF file.
instance of MSFT_ScriptResource as $MSFT_ScriptResource1ref
{
ResourceID = "[Script]MyScript";
GetScript = " @{CertFiles = (Test-Path \"C:\\ProgramData\\docker\\certs.d\\ca.cer\" )} \n ";
TestScript = " \n (Test-Path -Path \"$env:HOMEPATH\\FromScript.txt\") \n ";
SourceInfo = "C:\\gd\\Documents\\dockerswarmarm\\dsctest.ps1::18::9::Script";
SetScript = "\n [Scriptblock]::Create(\"'$privateKey' | out-file -FilePath '$env:HOMEPATH\\FromScript.txt' -Encoding ascii -Verbose\")\n #$privateKey | out-file -FilePath \"$env:HOMEPATH\\FromScript.txt\" -Encoding ascii -Verbose\n \n ";
ModuleName = "PsDesiredStateConfiguration";
jnury
February 27, 2018, 7:21am
5
I guess you placed the [Scriptblock]::Create(“”) inside your {}.
You should have something like that:
Script MyScript {
SetScript = [Scriptblock]::Create("'$privateKey' | out-file -FilePath '$env:HOMEPATH\FromScript.txt' -Encoding ascii -Verbose")
TestScript = [Scriptblock]::Create("(Test-Path -Path '$env:HOMEPATH\FromScript.txt')")
GetScript = [Scriptblock]::Create("@{CertFiles = '$env:HOMEPATH\FromScript.txt'}")
}
Output mof:
ResourceID = "[Script]MyScript";
GetScript = "@{CertFiles = '\\Users\\Julien\\FromScript.txt'}";
TestScript = "(Test-Path -Path '\\Users\\Julien\\FromScript.txt')";
SourceInfo = "::12::9::Script";
SetScript = "'test' | out-file -FilePath '\\Users\\Julien\\FromScript.txt' -Encoding ascii -Verbose";
ModuleName = "PsDesiredStateConfiguration";
But as said by Michael, you should create a custom resource. See https://docs.microsoft.com/en-us/powershell/dsc/authoringresourcemof
You’ll be able to easily reuse your ‘Ascci File DSC Resource’ and have a cleaner DSC recipe.
Note: your test function doesn’t actually test if the content of the file is correct.