Posts Tagged ‘Security’

postheadericon How to Import Binary Modules from Network Shares

Note: This is from a wiki page I just wrote on Importing Binary Modules from Network Shares which discusses not just the solution below that works for .Net 2.0 but also how to solve the problem on .Net 4.0 (e.g.: in PoshConsole). I will most likely not keep this page up to date, so you should refer to that wiki if you need more information.

Almost every author of a binary module has probably had someone ask about this at some point, because there’s always someone who has their user profiles stored on a network location, and therefore installed their modules on that network path and can’t get them to load because they get a warning that .Net “Failed to grant minimum permission requests.”

Before we get into this any further let me just say: by far the simplest thing to do is to create a local folder on your local hard drive, add that to your environment PSPathModules variable, and just install your modules there.

Other than that, the solution depends on the version of .Net that you’re using (you can tell by checking the $PSVersionTable.CLRVersion

The .Net 2.0 framework (and 3.0 and 3.5 and 3.5 SP1)

The problem is not a PowerShell problem at all, it’s a .Net problem. The .Net framework 2.0 (remember that PowerShell targets 2.0, and is actually based on .Net 1.1) didn’t trust assemblies loaded from network shares. You can fix that for an individual assembly or for a whole share using the Caspol tool.

A complete discussion of that tool and it’s myriad command-line options is beyond me, but for a simple solution, you can run this command specifying the server and share you want to load from (in my example the “Modules” share on the “ProfileServer” server).

Set-Alias CasPol "$([Runtime.InteropServices.RuntimeEnvironment]::GetRuntimeDirectory())CasPol.exe"
CasPol -pp off -machine -addgroup 1.2 -url file://\ProfileServer\Modules\* FullTrust

Hopefully the only thing that needs explaning there is that 1.2 is the default “Local Intranet” group, and that CasPol.exe is in your Framework Runtime directory. Once you’ve run that, you’ll be able to import any modules that are in subdirectories of that share.

Note: You must run the version of CasPol.exe which is in the lcation defined by the GetRuntimeDirectory() command (it’s important to use the same version as the runtime you want to be affected).

You can read more about importing binary modules from network shares, including how it changed in .Net 3.5 SP1 and why it’s not automatically fixed in .Net 4 over on the PoshCode wiki. :)

postheadericon A Better Get-Credential in one line of code

For too long I have ignored the deficiencies in Get-Credential, so now I am going to fix them. Ready?


function Get-Credential($caption,$msg,$domain,$name){$Host.UI.PromptForCredential($caption,$msg,$name,$domain)}

Ok, that’s better than the default, whew! ;) At least you can specify the prompt text and the domain and default user name … but there are so many other options that are missing from that dialog —like remembering my credentials for goodness sakes. I know many places forbid using the “remember” option for credentials, but why is that decision not up to me?

Well, I can’t make all of those options appear (at least, not without compiling a pinvoke function to call the Win32 API) nor can I force PowerShell to use the new Vista/2008 Credential function (which is Common Criteria compliant in Vista) instead of the older CredUIPromptForCredentials ... but I can give you the most requested feature for Get-Credential: a -Console option to force the prompt to happen in the console instead of in a “CredUI” pop up.

[new] Note: I kind-of messed up here, this will break if you’re used to using the -Credential parameter for Get-Credential to provide a default user name. I’ll fix it shortly.

postheadericon Code Signing with OpenSSL and PowerShell

One of the major security features of PowerShell is the support for code signing of scripts, so that you can set an execution policy that requires scripts to be signed before they can be run. Of course, it goes a bit further than that. When a script has been signed by a certificate with a root Certificate Authority (CA) that you don’t already “know” or trust it can’t be run at all until you add the root CA to the system’s certificate store.

Even after you trust a specific authority, you haven’t trusted a script author — so any signed script you run will prompt you whether you want to allow it or not, like so:

[19]: .\test-script.ps1

Do you want to run software from this untrusted publisher?
File C:\Users\Joel\Documents\WindowsPowerShell\test-script.ps1 is published by
E=NoUser@HuddledMasses.org, O=Huddled Masses, L=Rochester, S=New York, C=US
and is not trusted on your system. Only run scripts from trusted publishers.
[V] Never run [D] Do not run [R] Run once [A] Always run [?] Help (default is “D”):

The important thing to note here is that you’re really being asked not about the script, but about the author. If you choose the Never or Always options, the certificate that was used to sign the script is added to the appropriate certificate store (“Untrusted Certificates” or “Trusted Publishers”, respectively). To be clear: this happens for each every new author certificate, regardless of whether it’s signed by a self-signed cert (where you’ve already installed the root certificate in your root store) or a certificate issued by a commercial CA — there’s no loophole, no matter what anyone may have said in the past.

So, you see … the support for code signing is built into the core of PowerShell — and it’s really a shame not to take advantage of it. There are plenty of articles out there about how to sign your scripts, and more, so I’m not going to get into that much — I want to address the question of how hard it is to create the certificates in the first place (and finish by giving you a sample script which will generate and import them to your dev box with a single line command).

Read the rest of this entry »
Archives