3

I am trying to encrypt a folder (with windows EFS) in a programmatic manner. The following powershell code works just fine when ran via ISE powershell console.

$obj = New-Object -TypeName System.IO.FileInfo 'D:\Temp'      
$obj.Encrypt()

However running this under impersonated user via a chef recipe with test-kitchen produces this error below

recipe wrapper for the powershell:

ruby_block 'Enable encryption on folder' do
  block do
 command = <<-EOH
   # Encrypt the folder
   $obj = New-Object -TypeName System.IO.FileInfo 'D:\\Temp'      
   $obj.Encrypt()
   EOH
   powershell_out!(command, { user: username, password: pwd,
                           domain: domain})
  end
end

Results in the following stack trace:

PSMessageDetails      : 
Exception             : System.Management.Automation.MethodInvocationException:
                     Exception calling "Encrypt" with "0" argument(s): 
                    "The parameter is incorrect.
                    " ---> System.IO.IOException: The parameter is 
                    incorrect.

                       at System.IO.__Error.WinIOError(Int32 errorCode, 
                    String maybeFullPath)
                       at System.IO.File.Encrypt(String path)
                       at CallSite.Target(Closure , CallSite , Object )
                       --- End of inner exception stack trace ---
                       at System.Management.Automation.ExceptionHandlingOps
                    .CheckActionPreference(FunctionContext funcContext, 
                    Exception exception)
                       at System.Management.Automation.Interpreter.ActionCa
                    llInstruction`2.Run(InterpretedFrame frame)
                       at System.Management.Automation.Interpreter.EnterTry
                    CatchFinallyInstruction.Run(InterpretedFrame frame)
                       at System.Management.Automation.Interpreter.EnterTry
                    CatchFinallyInstruction.Run(InterpretedFrame frame)
TargetObject          : 
CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
FullyQualifiedErrorId : IOException
ErrorDetails          : 
InvocationInfo        : System.Management.Automation.InvocationInfo
ScriptStackTrace      : at <ScriptBlock>, <No file>: line 5
PipelineIterationInfo : {}

Notes: the user that's being impersonated is part of the Administrators group and has full control on D:\Temp. Another key observation is that if I perform an interactive login (RDP session) as that user before running chef via test-kitchen the recipe above succeeds without any issues and the folder gets encrypted locally just the same as if running powershell interactively in the console.

The exception seems to indicate that the path parameter to System.IO.File.Encrypt is not being set/passed somewhere inside, but I am at a loss why would this work one time and not the other. I did try to create the user profile by having recipe run an Invoke-Command against localhost as that user and it does create the profile e.g. (C:\users\... gets created), however the Encrypt() call still errors out with the same exception as above. This doesn't seem like a chef or a test-kitchen issue but rather something being missed on the powershell/windows side of things with the encrypted file system intricacies, any help is greatly appreciated.

Thank you

ostap36
  • 33
  • 6
  • This is on Win2k12R2, powershell 4.0, chef-client 12.13.37 – ostap36 Mar 15 '17 at 01:47
  • This should probably be removed here and filed as an Issue on our GH repo :) – coderanger Mar 15 '17 at 02:31
  • I'm not sure whether or not it is possible to access EFS files when the user's profile isn't loaded. [According to technet,](https://technet.microsoft.com/en-us/library/cc700811.aspx) that's where the underlying encryption keys are stored. That would explain why it works when the user is logged on. – Harry Johnston Mar 15 '17 at 03:07
  • @coderanger do you think this is an issue within chef-client? or rather mixlib-shellout? – ostap36 Mar 15 '17 at 03:12
  • @HarryJohnston yep that's what it looks like. My impression is that chef's shellout would facilitate that, so perhaps as coderanger suggests I should move this to a respective chef's github repo. However I am also open to any suggestions to augment powershell above such that it can perform that pre-requisite user profile load. – ostap36 Mar 15 '17 at 03:24
  • @ostap36 `chef/chef` to start with, if we need to fix it elsewhere but that gets it in front of the people that need to see it. – coderanger Mar 15 '17 at 04:06
  • In C, you would use the `LoadUserProfile` function to do this. If you can shell out to an executable or have some other way of calling the Win32 API, that might work. (It gets a bit tricky if you have roaming profiles, but that would be unusual on a server.) – Harry Johnston Mar 15 '17 at 20:21

1 Answers1

1

Unfortunately I do not believe you can encrypt files over a remote session. If you were to try this same operation over a native windows powershell remoting session, you would get a UnauthorizedAccessException. If you are using Test-Kitchen, try using the Elevated winrm transport.

Example yaml:

platforms: - name: eval-win2012r2-standard os_type: windows transport: name: winrm elevated: true

This simulates a local logon session and may workaround this error.

Matt Wrock
  • 6,590
  • 29
  • 23
  • Thank you Matt, unfortunately `elevated` didn't help, still same exception. However it does look like the issue is with the impersonation, if the "run as" credentials hash ```{ user: username, password: pwd, domain: domain}``` is removed from the powershell_out, the encryption succeeds. – ostap36 Mar 16 '17 at 00:19