Tag Archives: Code

String arrays and mandatory parameters

I have been working on a function to convert the output of NET SHARE <sharename> commands into usable PowerShell objects. In the course of my work, I was storing the output of the command in a variable, which I later pass into a parsing function. Curiously, the function I developed iteratively in the console worked fine, but when I dressed it up in my script, it failed:

test-array : Cannot bind argument to parameter 'foo' because it is an empty string.
At line:1 char:12
+ test-array $party
+            ~~~~~~
    + CategoryInfo          : InvalidData: (:) [test-array], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,test-array

I had verified that the variable was of type System.Array, and that it had string elements. After banging my head on it for a while, I decided to break out the parameter handling and test it separately. I wrote a quick function to accept and process the elements of a string array:

function test-array {
param( [string[]] $foo )
    $i = 0
    foreach ( $line in $foo ) {
        write "[$i] $line"
        $i++
    }
}

Continue reading

Listing parent of AD object in PowerShell

Recently, I wanted to provide a client with a list of groups that related to some work he was doing. I wanted the group names as well as their location with AD. Although I often use the ds* commands or excellent ADfind tool for this type of task, I had been working in PowerShell on another project, so I decided to use the PowerShell ActiveDirectory module.

The Get-ADGroup Cmdlet pulled out the groups easily enough, but the there wasn’t a property representing the group object’s parent, nor is there an LDAP property that I could request (AFAIK). The object’s parent is contained within the DistinguishedName (DN) property, though.

For a group with the following DN:

CN=FOO-FileServices Administrators,OU=FOO,OU=Departments,DC=uvm,...

I just need to strip off the CN. I could split the DN on commas, remove the first element, and then reassemble what’s left to get the parent. I also needed to avoid splitting on an LDAP-escaped comma where a value actually contains a comma (e.g., CN=).

PS> $dn -split '(?<![\\]),'

Continue reading

Script: Shadow Copy Report

We use EMC NetWorker for our enterprise backup solution. Since we migrated our primary file server from a NetApp filer to a native Windows server, we’ve been having a recurring problem with all the Shadow Copies for a volume getting deleted. There are strong indications that the problem is related to the NetWorker backups.

As we have been working on this issue with EMC (since the first week in January!), I wrote a script to tell me two things each morning; how many snapshots exist for each volume, and what VSS errors were logged, if any.

I thought someone might find it useful, so I’ve posted it as a separate page (the script doesn’t fit nicely in the column on the blog).

PowerShell Script: chksnap.ps1

Powershell Join-String function

Update: better yet, read about the -Join and -Split PowerShell operators. Live and learn.
—Geoff

Something I’ve found myself missing in PowerShell is a function to combing the elements of a list with a given separator, like Perl’s join() function. I finally got annoyed enought to write one. It seems to do what I want, so I’m going to add it to my profile.

Here it is in action:

PS C:\> $array = 3.14,'Puppy',$false,'','Green',$null,'foo'
PS C:\> $array | Join-String
3.14,Puppy,False,,Green,,foo
PS C:\> $array | Join-String -collapse
3.14,Puppy,Green,foo
PS C:\> $array | Join-String -collapse ' - '
3.14 - Puppy - Green - foo

Update: Now supports list items as parameter (non-pipeline) usage:

PS C:\> $y = Join-String $array -collapse
PS C:\> $y
3.14,Puppy,False,Green,foo
PS C:\> $y.gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

Here’s the code:

# Join-String - A simple pipeline-oriented function to
# concatenate a bunch of strings together with a separator
# Geoffrey.Duke@uvm.edu  Wed 11/17/2010
#   updated 11 July 2013 to handle non-pipeline usage

function Join-String
(   
    [string[]] $list,
    [string] $separator = ',',
    [switch] $Collapse
)
{ 

[string] $string = ''
$first  =  $true

# if called with a list parameter, rather than in a pipeline...
if ( $list.count -ne 0 ) {
    $input = $list
}

foreach ( $element in $input  ) {
    #Skip blank elements if -Collapse is specified
    if ( $Collapse -and [string]::IsNullOrEmpty( $element)  ) {
        continue
    }

    if ($first) {
        $string = $element
        $first  = $false
    }
    else {
        $string += $separator + $element 
    }
}
 
    write-output $string
}

If you have a notion for how it could be improved, please comment.