Fixing PowerShell’s Copy-Item “Access is Denied” Error

Recently I needed a way to copy a certificate file from within a PowerShell session to another Windows machine without opening a nested PowerShell session. But I ran into a little snag along the way: Copy-Item‘s dreaded Access is denied error.

Here’s my setup:

  • A Windows 10 laptop, from which I’m remoting
  • NC1, a Server 2016 virtual machine I’m remoted into. It’s a member of a domain.
  • HYPERV1, the Server 2016 machine I want to copy a certificate file to. It’s not a member of a domain.

I execute all of the following commands on NC1, the VM I’m remoted into.

Here’s the first thing I tried. The HYPERV1 machine is not a member of a domain, so the following doesn’t work:
$ Copy-Item .\nccert.cer \\hyperv1\c$
Access is denied
+ CategoryInfo          : NotSpecified: (:) [Copy-Item], UnauthorizedAccessException
+ FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.CopyItemCommand

What about specifying the -Credential parameter? That doesn’t work either.
$ Copy-Item .\nccert.cer \\hyperv1\c$ -Credential hyperv1\administrator
The FileSystem provider supports credentials only on the New-PSDrive cmdlet. Perform the operation again without specifying credentials.
+ CategoryInfo          : NotImplemented: (:) [], PSNotSupportedException
+ FullyQualifiedErrorId : NotSupported

And that error pretty much tells me what I need to do: use the New-PSDrive cmdlet!
$ New-PSDrive -Name H -PSProvider FileSystem -root \\hyperv1\c$ -Credential hyperv1\administrator
$ Copy-Item .\nccert.cer h:\
$ Remove-PSDrive -Name H

Creating a File Share with PowerShell and Windows Server Core

Sometimes you just need to create a file share.

With Windows Server Core, you don’t have all the old GUI tools that we’re all used to. So you have to make do with PowerShell and the old fake DOS prompt. Fortunately, with a little help, it’s pretty easy.

First, create the folder you want to share. In this case, c:\share

Next, modify the ACL to grant the DOMAIN\File Server Admins group full control

$sharepath = "c:\share"
$Acl = Get-ACL $SharePath
$AccessRule= New-Object System.Security.AccessControl.FileSystemAccessRule("DOMAIN\File Server Admins","full","ContainerInherit,Objectinherit","none","Allow")
$Acl.AddAccessRule($AccessRule)
Set-Acl $SharePath $Acl

Finally, create the share and grant everyone full access.
NET SHARE sharename=c:\share  "/GRANT:Everyone,FULL"

Done.

Building Windows Server with Puppet and Chocolatey

Forget using scripts and group policies to configure a new Windows Server machine. Using Chocolatey and Puppet, you can do it faster & easier than ever (and it’s more fun too). This is especially true if you’re using a Server Core installation and don’t have a GUI to help you along. Oh, and if you don’t know Puppet, you really should watch my course Puppet Fundamentals for System Administrators on Pluralsight 🙂

Assign IP address using PowerShell:

$ New-NetIPAddress –InterfaceAlias "Ethernet" –IPAddress "192.168.51.29" –PrefixLength 24 -DefaultGateway 192.168.51.8

$ Set-DnsClientServerAddress -InterfaceAlias “Ethernet” -ServerAddresses 192.168.50.20, 192.168.50.21

Install Chocolatey:

$ set-executionpolicy unrestricted
$ iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))

Restart PowerShell

Install VMware tools

$ choco install vmware-tools

The server will automatically restart.

Rename server

$ rename-computer -newname newservername

Reboot

restart-computer

Join to domain
add-computer -domain benpiper.com

Reboot again
restart-computer

Install Puppet
choco install puppet

Configure Puppet
Configure c:\programdata\puppetlabs\puppet\etc\puppet.conf

Generate puppet certificate
puppet_interactive

Sign puppet certificate on puppet master
puppet cert sign newservername

Apply appropriate profiles to server. Remember to restart the Puppet master if you change your Hiera configuration.

Run Puppet agent
puppet_interactive

Verify
puppet resource dism
puppet resource package

Windows Server Core Full Configuration with PowerShell

How to Configure Server Core with Active Directory Services, DNS, and DHCP Using Nothing But PowerShell

Windows Server 2012 offers two installation options: Server Core or “Server with a GUI”. This begs the question: Why would you want to install Server Core instead of the GUI? One reason may be that you have limited physical hardware resources and want to keep the footprint as small as possible.

Recently I needed to build a domain controller, DHCP, and DNS server for a branch office. This office has a Riverbed Steelhead WAN optimization appliance which runs a nested VMware ESXi hypervisor. The appliance has limited memory and disk space, so I needed to keep the installation as small as possible (Incidentally, if I only needed DNS and DHCP, I would have just installed RedHat Enterprise Linux, but having the server be an Active Directory domain controller was also a requirement.)

I’m going to show you step-by-step how I configured Active Directory Services, DNS, and DHCP on a Windows Server 2012 Server Core installation. Continue reading

Forcing Apps to Run in 32-bit mode in 64-bit Windows

Have you ever had an application that seemed to initially run fine under Windows x64, only to have it crash or complain when performing a certain function inside the app? I have noticed this in a couple of applications that hook into Crystal Reports to display reports inside the app. If you’ve run into this problem, take heart because the fix is really simple.

But first, it’s helpful to understand what happens when you run an application under 64-bit Windows. Some applications and libraries (DLLs) are compiled in such a way that they can run either as native 64-bit or 32-bit mode. Other applications and DLLs, however, can only run as 32-bit.

Let’s say you have an application that easily runs as a 64-bit app under Windows 2008 R2 (which is a 64-bit OS). No problem, right? But what if that app makes a call to a Crystal Reports DLL that is compiled only as a 32-bit DLL? Trouble! That’s what happens! The application will not be able to find the DLL. As far as the app is concerned, the DLL doesn’t exist.

To understand why, we must understand how Windows separates 32 and 64-bit components. Windows x64 stores 32-bit DLLs in the Windows\SysWoW64 folder, while 64-bit DLLs go in the Windows\System32 folder. That seems backwards, doesn’t it? But it gets even more counter-intuitive. When a 32-bit mode application runs under Windows x64 and wants a DLL from “c:\windows\system32”, Windows will “lie” to the app and give it the DLL from C:\windows\syswow64!

The flipside of this redirection scheme is that 64-bit apps are affected as well. 64-bit applications cannot see or access the Windows\SysWoW64 folder. They can only see Windows\System32. If an application installer places a 32-bit DLL in Windows\SysWoW64, then later a 64-bit application tries to call that DLL, it will simply fail because, to the application, that DLL doesn’t exist.

But what if we get sneaky and copy that 32-bit DLL to the System32 folder? Our 64-bit app will find the DLL, but it will not be able to load it into its memory space (For a technical explanation why, see Why can’t you thunk between 32-bit and 64-bit Windows?). Once again, the app will crash or yield an error.

So what is the solution? We just have to get the 64-bit app to run as a 32-bit application. This will allow the app to see the 32-bit DLLs in the Windows\SysWoW64 folder and load them into its memory space. We will lose some of the benefits of 64-bit execution, but at least the app will work properly. And fortunately, we don’t have to get the vendor to send us a recompiled executable. We can force the app to run as a 32-bit app by changing the execution headers using the Microsoft CorFlags utility. All you have to do is install the Microsoft Windows SDK and grab CorFlags.exe from the Bin folder of the SDK program files directory.

Then all you have to do is run:

CorFlags /32BIT+ application.exe

where application.exe is the application you want to force to run as 32-bit. The next time you execute the application, Windows will see the new header and will execute it as a 32-bit application.