1

I am creating a JSON file using powershell and using the JSON file as a chef-runtime attribute.

Code to create JSON file (in powershell)

New-Item $ATTRIBUTESFILE -ItemType file
$jsonInput = @{param1=@{subparam=$attribute}}
$ATTRIBUTE = $jsonInput | ConvertTo-Json
$ATTRIBUTE | Out-File $ATTRIBUTESFILE

Code to call the chef-client

chef-client -o 'recipe[cookbook]' -j $ATTRIBUTESFILE

Error message

c:/chef/embedded/lib/ruby/gems/1.9.1/gems/yajl-ruby-1.1.0-x86-mingw32/lib/yajl.rb:36:in `parse': lexical error:
invalid char in json text. (Yajl::ParseError)
                                   ÿ_{                     (right here) ------^
    from c:/chef/embedded/lib/ruby/gems/1.9.1/gems/yajl-ruby-1.1.0-x86-mingw32/lib/yajl.rb:36:in `parse'
    from c:/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.6.0/lib/chef/json_compat.rb:56:in `from_json'

When I create the same file manually, it gives no lexical error. Any help on this would be appreciated.

Ayush
  • 81
  • 1
  • 7

2 Answers2

1

Add -Encoding UTF8 to the Out-File. That's probably a UTF-16 byte order mark.

coderanger
  • 52,400
  • 4
  • 52
  • 75
  • Indeed, `Out-File` by default creates a UTF-16LE file (with BOM) by default (as does `>`); note that using `-Encoding UTF-8` also creates a BOM, however - can Chef handle that? – mklement0 Mar 26 '18 at 02:06
  • No, we assume normal file handling everywhere. – coderanger Mar 26 '18 at 02:42
  • Also why would UTF-8 need a BOM? – coderanger Mar 26 '18 at 02:44
  • The Unicode standard neither encourages nor discourages a UTF-8 BOM (which would more properly be called a Unicode signature). In the Unix world, most utilities neither produce a BOM when they write a UTF-8 file, nor do they know how to handle one when they read a file. Unfortunately, in the Windows world it is common to use one for the sake of backward compatibility: files without a BOM continue to be interpreted as "ANSI"-encoded. Fortunately, the cross-platform _Core_ edition of PowerShell has seen the light and now defaults to BOM-less UTF-8 too. – mklement0 Mar 26 '18 at 03:01
1

Windows PowerShell creates UTF-16LE-encoded files (with a BOM) with Out-File and > by default.[1]

By contrast, Chef requires UTF-8-encoded files without a BOM, according to coderanger. Unfortunately, using -Encoding UTF8 invariably creates UTF-8 files with a BOM in Windows PowerShell. The solution is to use the .NET framework directly:

[System.IO.File]::WriteAllText($ATTRIBUTESFILE.FullName, $ATTRIBUTE)

See this answer of mine for a convenience function that produces BOM-less UTF-8 files with syntax similar to Out-File.


[1] In PowerShell Core, UTF-8 without BOM is now the default encoding.

mklement0
  • 382,024
  • 64
  • 607
  • 775