• PowerShell to assign permission to a folder (not copy inherited permissions)

    In my previous post, I used PowerShell to change the permissions of a top level folder. In that script, I took the folder in question and copied the inherited permissions to it, and then I tinkered it to be what I wanted. I wanted to do something similar, but I wanted a set of permission that differed from the parent. Basically I wanted the folder to have unique permissions. Below is the function to do that:

    function JBMURPHY-PERMS-ClientsFolderReBase {
        Param([parameter(Mandatory = $true)]$Path)
        $correctACLs = New-Object System.Security.AccessControl.DirectorySecurity
        $correctACLs.SetAccessRuleProtection($true,$true)
        $Rule_Admin = New-Object Security.AccessControl.FileSystemAccessRule("BUILTIN\Administrators",@("FullControl"),"ContainerInherit, ObjectInherit","None","Allow")
        $Rule_System = New-Object Security.AccessControl.FileSystemAccessRule("NT AUTHORITY\SYSTEM",@("FullControl"),"ContainerInherit, ObjectInherit","None","Allow")
        $Rule_Users1 = New-Object Security.AccessControl.FileSystemAccessRule("BUILTIN\Users",@("ReadAndExecute", "Synchronize"),"None","None","Allow")
        $Rule_Users2 = New-Object Security.AccessControl.FileSystemAccessRule("BUILTIN\Users",@("Modify, Synchronize"),"ContainerInherit, ObjectInherit","InheritOnly","Allow")
        $correctACLs.AddAccessRule($Rule_Admin)
        $correctACLs.AddAccessRule($Rule_System)
        $correctACLs.AddAccessRule($Rule_Users1)
        $correctACLs.AddAccessRule($Rule_Users2)
        write-host "Changing $Path"
        set-acl $path $correctACLs
    }
    

    In line 3 I create a new ACl, and in line 4, I set the cal to not inherit parent permissions.

    Lines 4-8 are the specific permissions I want to apply (they are addressing the same issue I described here)

    Lines 9-12 add the new perms to the new ACL, and line 14 set the ACL of the folder to the new ACL.

    A little different want o go about this, as I created an ACL from the start.


  • CentOS 6 in a VM – Console resolution

    I can NEVER remember this, and every time I re-install CentOS in a VM I have to go searching.

    If you want the console size to be larger in a vm add vga=791 (for 1024×768) to the end of the kernel line in /etc/grub.conf.

    The VESA values (for linux) are here


  • How to add Gnome to a CentOS 6 minimal install

    I have been using the minimal iso (CentOS-6.0-x86_64-minimal.iso) to install CentOS 6. I wanted to add a GUI to my vm, but I could not find easy documentation showing how to add a GUI, or Gnome in this case, to a CentOS 6 minimal install. I was not looking for the smallest X windows install, I was just trying to get the Desktop to function like it would as if I installed from the full DVD.

    There are a lot of results of how to do this, but things have been renamed in CentOS 6, so that made it more difficult to figure out. Also, there are “Short Names” and I am assuming they are called “Long Names” associated with a yum groupinstall, which added to my confusion.

    To add Gnome/GUI to a minimal CentOS 6 install run (short name version):

    yum groupinstall basic-desktop desktop-platform x11 fonts

    And the “long name” version:

    yum groupinstall "Desktop" "Desktop Platform" "X Window System" "Fonts"

    Hope that helps someone or at least help me to remember.


  • Back to 2000 visitors a month!

    September and October we light. Backup up at 2000 for November! I better get busy if I ever want to hit 3000!


  • PowerShell: Return, ForEach,ForEach-Object and a pipe

    I just figured this out late last night. I was pulling my hair out. If you look at the following PowerShell code

    ($MyArray=1,2,3,4,5) | foreach-object {
    write-host $_
    if ($_ -eq 3 ){return}
    }
    

    You get a result of:
    1
    2
    3
    4
    5

    Next, if you look at this code (the only real difference being the lack of a pipe.)

    foreach ($item in ($MyArray=1,2,3,4,5)) {
    write-host $item
    if ($item -eq 3 ){return}
    }
    

    You get:
    1
    2
    3

    That stumped me. Why would they not produce the same thing? Then I ran across this thread. The replier said

    I think because ForEach-Object processes each item in the pipeline, but the foreach statement processes the collection as a whole.

    This led me to this page, and specifically this quote clears it up for me (kinda):

     . . . [the object] it is sent into the pipeline and execution continues in the next section of the pipeline.  . . . the foreach alias gets executed and the object is run through the process script block of ForEach-Object.  Once the process script block completes, the object is discarded and the next object is [sent] . . .

    In summary, last night I learned that when using a pipeline, the first item is passed to the script block, the script block is run, and then the next item is passed to the script block, and so on.

    That sound correct? Can you come up with a better description?


  • PowerShell code to split a space delimited string – with double spaces

    I am working on a PowerShell wrapper script to run multiple commands on multiple machines. The first thing I wanted to do was to chop up a space or comma delimited argument. (If you make an argument mandatory, and the user does not provide it, PowerShell will prompt you for it – and when prompted you can use space delimited values).

    I was going to use the split() function, but I did not know how to handle “multiple spaces”. For example:

    ("123  4 5678").Split() = 
    123
     
     
    4
    
    5678"
    

    I would end up with “empty” array members. I found this post, and they guy used “| where-object {$_ -ne ”“}” to filter out the empty values. But then I stumbled upon a better way to do it, using the built in “StringSplitOptions” of  RemoveEmptyEntries.

    ("123  4 5678").split(" ",[StringSplitOptions]'RemoveEmptyEntries')

    would result in:

    123
    4
    5678
    

    If you don’t know if you are going to have space or comma delimited then I used:

    $Argument.split(" ",[StringSplitOptions]'RemoveEmptyEntries') | foreach {
    $_.split(",",[StringSplitOptions]'RemoveEmptyEntries')}
    

  • PowerShell wrapper scripts to find locked accounts and prompt to unlock

    I wanted a quick way to find if an account is locked out (you get the call “I can’t log in”) and unlock it. I had a wrapper script that just called “Search-ADAccount –LockedOut” but I took it a bit further. The first of these two wrapper scripts/functions gets all the accounts that are  locked out, then it asks if you want to unlock the account – if yes, it calls the second unlock function. If no, then it loops to the next locked account.

    function JBMURPHY-AD-GetLockedOut {
    	Search-ADAccount –LockedOut | foreach-object {
    	$UserName=$_.Name
    	$SamAccountName=$_.SamAccountName
    	write-host "`n$UserName is locked out`n"
    	$message = "Do you want to unlock $UserName"
    	$yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes","Yes nnlock $UserName"
    	$no = New-Object System.Management.Automation.Host.ChoiceDescription "&No","No, don't unlock $UserName"
    	$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
    	$result = $host.ui.PromptForChoice($title, $message, $options, 0)
    	if ($result -eq 0){
    		JBMURPHY-AD-UnlockAccount -UserName $SamAccountName
    	}
    	}
    }
    

    The second function is a simple script that wraps the unlock-adaccount function:

    function JBMURPHY-AD-UnlockAccount {
    	Param([parameter(Mandatory = $true)]$UserName)
    	Unlock-ADAccount -Identity $UserName
    }
    

  • Start Visual Studio form PowerShell

    I am moving on to a new project – our migration from SharePoint 2007 to 2010. First thing I wanted to do was to upgrade my Solutions/Features from 2007 to 2010. I installed Visual Studio and started looking at how to recreate my Delegate JQuery Control (more on that later). The first thing I found annoying was that every time I added an “Empty SharePoint Project”, I received a warning “This task requires the application to have elevated permissions”. That is annoying. Since I usually leave a PowerShell prompt running as administrator (It has a red background to distinguish it), I wanted to quickly open VisualStudio from that PowerShell prompt. Here is my wrapper script to open VisualStudio 2010 from PowerShell:

    function JBMURPHY-Start-VisualStudio {
    Start-Process "C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe" -workingdirectory "C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\"
    }