date_modified: Invoke-SEFAUtil

#en, #powershell, #lync, #skype4b edit this page

Some weeks ago, I’ve written about my PowerShell wrapper function for SEFAUtil.exe, the original post can be found here: /post/Invoke-SEFAUtil-a-PowerShell-wrapper-function.aspx

GUI

First of all, in case you haven’t seen it yet, MVP Johan Veldhuis created an AWESOME GUI wrapper. Check it out: http://johanveldhuis.nl/en/sefautil-gui/

If you still want to run it via PowerShell, keep on reading ;)

Updated Script

After playing around with my script I figured it would be cool if it would return more “PowerShell like” objects instead of the plain text returned by sefautil.exe. I also wanted it to take pipeline input and updated the related links to point to a help page instead of the blog article.

Turning a bunch of strings into a PowerShell object

Looking at the text output of the tool, we can see it has a format of “description : value”.

Sample output:

User Aor: sip:[email protected]
Display Name: Thomas Torggler
UM Enabled: True
Simulring enabled: False
User Ring time: 00:00:30
Call Forward No Answer to: voicemail

As they have the same structure, this does immediately bring PowerShell dictionaries (hashtables) to mind. I simply used the –split method to split the strings at “: “ (colon space) and saved the result to a new array.

$SEFAResultSplit = $SEFAResult -split ': '

This worked as expected, so I went ahead and created my custom object like this:

$data =  @{$SEFAResultSplit[0] = $SEFAResultSplit[1];
$SEFAResultSplit[2] = $SEFAResultSplit[3];
}

After testing it in the lab, I realized, even though this worked, it was less then ideal. Sefautil returns a dynamic amount of strings depending on which features are configured for the given user. So while it was reasonably sure that ”$SEFAResultSplit[0]” would always be “User Aor”, I would have no way of knowing the value of the next strings. And, more importantly, I would not know how many strings to expect, a more dynamic approach was needed.

This is what I came up with after some serious head scratching:

for ($i = 0; $i -lt $SEFAResultSplit.Count; $i++) {
    if ([bool]!($i%2)) {
        $j = $i + 1
        $outData += @{$SEFAResultSplit[$i] = $SEFAResultSplit[$j]}
    }
}

And here is what it does: The array that contains the split strings would always contain the “description” at an even number while the actual values would be found at odd numbers. So, the script loops through the array, and for each even number it creates a new “Key : Value” pair that is saved to a hash table.

Whatever object in the array is at the even index number would be used as key, and that even number +1 would be used as value. Sweet.

Why?

Well, first of all, because it’s cool ;)

Then, think about this:

Get-CsUser –OU "OU=users,OU=Italy,DC=tomt,DC=local" | .\Invoke-SEFAUtil.ps1 –Server ly15.tomt.local | Where-Object {‘Simulring enabled’ –eq $true}

First the Get-CsUser cmdlet is used to get all users within a specified organizational unit, the user objects are then piped into my wrapper script and the output can be filtered just like any other PowerShell output. Of course it could also be converted to html or exported to csv, the point is returning objects instead of text.

Sure enough, we can now also take advantage of pipeline input processing to set call forwarding settings for multiple users:

Get-CsUser -OU "OU=users,OU=Italy,DC=tomt,DC=local" | .\Invoke-SEFAUtil.ps1 -Server ly15.tomt.local -Verbose -AddDelegate [email protected]

Again, we use Get-CsUser to get some Lync Users and pipe them to the script, which adds [email protected] as a delegate to the every one of the users.

Download

I’ve updated the script on my Sky Drive, find a link at the new help page.

Cheers,
tom