Sunday, April 26, 2009
OCS 2007 R2 Edge Certificate Wizard gotcha
We were using the OCS 2007 R2 Edge Server setup wizard to request certificates for the external interfaces. This particular customer uses GoDaddy for their certificates. We created an offline request and pasted the CSR into GoDaddy's request interface - and were promptly told that the CSR was not valid.
What we discovered was this: The customer's OCS R2 Edge server was running Windows Server 2008. When we created the certificate request using the setup wizard, the -----BEGIN CERTIFICATE REQUEST----- header and -----END CERTIFICATE REQUEST----- trailers were not inserted into the file. This was what threw the error when we pasted the CSR into GoDaddy's interface.
To solve this and be able to get our certificate from GoDaddy, we simply pasted correctly formatted header and trailer lines into the CSR, which was then accepted as a proper CSR file.
If OCS R2 Edge is deployed on Windows Server 2003 R2, the certificate request header and trailer is inserted into the request file generated by the setup wizard, so the issue looks to be specific to deployments on Windows Server 2008.
It is worth noting that if you use IIS on Windows Server 2008 to create an SSL certificate request, the -----BEGIN CERTIFICATE REQUEST----- and -----END CERTIFICATE REQUEST----- lines are included in the generated CSR file - so "normal" IIS certificate requests created on Windows Server 2008 are not affected.
Friday, April 24, 2009
How to install Exchange 2010 and Exchange 2010 UM
If you want to play with Exchange 2010 UM, then here are two links on two different blogs that will help you -
How to Install Exchange Server 2010 Beta
How to Install Exchange Server 2010 Unified Messaging Beta
Happy installing ;-)
Friday, April 17, 2009
Regex – Still a Lot to Learn…
I though I was pretty good with Regex’s - but just realized that even if I use it a lot – there are still a lot of things to learn. And Regex (I’m using the .Net version) is very powerfull.
The other day, I was searching for some useful regex’s, as I wanted to test for invalid email domain – e.g. the positive ones should be matched and the rest should be trapped. During this search, I stumbled across RegexBuddy and I decided to spent the €30 to buy it. And that had really sped up my learning! After getting the grips for the interface, it is very useful. First of all, no more repetitious string –replace pattern from PowerShell. Now everything is shown in color – live – and you can trace things down and even build the thing using graphical bricks.
So what have I learned so far?
Replacing each space in the start of a string/line – e.g. replace leading spaces with – is easy (now) -
$line -replace '(?<=(^ *)) ',' '
Splitting a distinguished name – taking escaped characters into account – also simple -
# PowerShell V1
[regex]::split($dn,'(?<!\\),')
# PowerShell V2 CTP3
$dn -split '(?<!\\),'
And how about writing a CSV with another delimiter than comma in PowerShell V1. I did a Convert-TsvToCsv earlier and have also written Export-Tsv (not published). But it can be done so easy with a regex that I’m almost ashamed over all the work I have done -
function Export-DelimitedFile($file,$delimiter=";") {
$work=Join-Path $env:temp ($myinvocation.mycommand.name + $pid + ".temp")
$input | Export-Csv $work
(type $work) -replace '("[^"\r\n]*")?,(?![^",\r\n]*"$)',"`$1$delimiter" | out-file $file
}
Have so much regex fun!
Wednesday, April 15, 2009
Making PowerTab 0.99 Beta 2 work on PowerShell V2 (CTP3)
Being very fond of PowerTab, it has been a loss that it did not work for PowerShell V2. But it turns out to be very simple to fix the problem. It fails as the parameter signature for $host.ui.rawui.NewBufferCellArray seems to have changed in V2.
Fixing the problem is a matter of changing two lines in <PowerTabDir>\TabExpansion.ps1. The old line is commented out -
# $message = $host.ui.rawui.NewBufferCellArray(@('[Tab]'),'Yellow','Blue')
$message = $host.ui.rawui.NewBufferCellArray(@('[Tab]'),[consolecolor]::Yellow,[consolecolor]::blue)
and
# $message = $host.ui.rawui.NewBufferCellArray(@('[Err]'),'Yellow','Red')
$message = $host.ui.rawui.NewBufferCellArray(@('[Tab]'),[consolecolor]::Yellow,[consolecolor]::red)
Have fun!
PS: It does not work in ISE
Friday, April 10, 2009
Want to dial 1-800-flowers or 1-866-MSONLIN from OC ?
Many don’t realize that this is possible from Office Communicator (RTM or R2) – allthough I have showed it to the students at most of my boot camps.
OC according to my testing supports what is called E.161 mapping of characters to numbers (also known as ANSI T1.703-1995/1999, and ISO/IEC 9995-8:1994 or most probably similar to what you see on your mobile phone), so if you write e.g. +1800flowers in your OC client it will look like this -
The only rule is that you have to start with a number, otherwise the client will think that you are trying to lookup a person in the Address Book.
As you may know Microsoft supports RFC3966 and here is what the RFC says about this (Thx to Dennis Klama for this pointer) -
5.1.2. Alphabetic Characters Corresponding to Digits
In some countries, it is common to write phone numbers with alphabetic characters corresponding to certain numbers on the telephone keypad. The URI format does not support this notation, as the mapping from alphabetic characters to digits is not completely uniform internationally, although there are standards [E.161][T1.703] addressing this issue.
What happens in OC, is that the character/number mapping is taking place client side and therefore the actual URI only consists of numbers.
Furthermore, my testing shows that OC supports the International standard for character to number mapping, but you should be aware that different countries in the past have had different regional implementations of the mapping. Furthermore the use of vanity numbers is unusual in Europe.
For your reference I have created a table mapping of characters/numbers that OC and E.161 uses
| abc | def | ghi | jkl | mno | pqrs | tuv | wxyz |
| 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
Automated Maintenance of Directory Service Restore Mode Password
With Windows Server 2008 SP2 or SP1/RTM with hotfix KB961320 you can make administration of the DSRM password completely automatic. The approach is this: You create an unprivileged account in Active Directory, set the password and using a scheduled task you execute the new sync from domain account xxxx command.
This nice approach is documented in the Directory Services blog. Read the complete story here.
Thursday, April 09, 2009
MVP for yet another year ;-)
Dear Dennis Thomsen,
Congratulations! We are pleased to present you with the 2009 Microsoft® MVP Award! This award is given to exceptional technical community leaders who actively share their high quality, real world expertise with others.
At Microsoft, we believe that technical communities enhance people’s lives and the industry’s success because independent experts, like you, help others extract greater value from products and technologies through the free and objective exchange of knowledge. As a Microsoft MVP, you are part of a highly select group of experts that represent technology’s best and brightest who share a deep commitment to community and a willingness to help others.
On behalf of everyone at Microsoft, thank you for your contributions to technical communities.
Thank you to Microsoft for the award, I really appreciate working with Microsoft and getting access to the information and resources that the MVP award opens up for.
More information about the ability to NAT the R2 A/V Edge Service (So no public IP is needed)
Stumbled over this excellent article with good information on how to setup the R2 A/V Edge, firewall for SNAT’and DNAT etc. It includes nices captures of the SIP traffic / candidates so it’s well worth the read. Read the post from Rick Varvel here - Configuring R2 A/V Edge Service for NAT.
Connectivity information in OC 2007 R2
My colleague, Claus-Ole, just pointed me to a neat trick that I didn’t know of. In OC you can, like in Microsoft Outlook 2007, press Ctrl key while right-clicking the OC Icon and voila up comes a menu item called “Configuration information” -
Where you get a lot of information on your connection type, autoconfiguration ABS download etc. Read more about this neat little feature at the source Office Communicator Configuration Information.
Tuesday, April 07, 2009
PowerShell, Getting the Value Out of a ScriptBlock
When you are doing a little advanced scripting and passing scriptblocks around, one of the problems I encountered was how to execute the scriptblock in a pipeline and get the value out of it. Say you want the user to be able to enter a scriptblock and compare your data to the value returned from it – how is that done?
Executing a scriptblock is easy using the &-operator
$sb={"Hello World!"}
&$sb
You can also use the invoke method -
$sb.invoke()
If you want to have a filtering scriptblock e.g. comparing a value with a scriptblock (not its value), I found it easy and logical to use where(-object) -
$sb={$_.name –like ‘note*’}
dir $env:windir | where $sb
# or
if (dir $env:windir | where $sb) {"Slipped through filter, go on"}But what if you want to execute it, feeding in values from the pipeline to get new values? (Often you would only send in one value at a time). The answer is foreach(-object) -
$sb={$_.name.toupper()}
dir $env:windir note* | foreach $sbWhen can this be useful? In numerous places, I would say. What if you have some getter script, with these arguments -
Get-XXX –dateproperty <property>
–value <value|scriptblock>
–filter <scriptblock>
If this case the code is something like (pseudo code) -
get-object | where &$filter| foreach {
if ($value –is [scriptblock]) {
$compareto=$_ | foreach $value
else {
$compareto=$value
}
if ($_.$dateproperty –gt $value) {
“ok”
}
}
# Getting files accessed after January 1st
get-xxx–dateproperty lastAccessTime –value ([datetime] "2009-01-01")
# Getting files accessed 90 days after it was modified
get-xxx–dateproperty lastaccesstime –value {$_.lastwritetime.adddays(90)}
What is REST?
Saturday, March 28, 2009
Free PowerShell eBooks
Just read/browsed two free PowerShell eBooks and here are my comments -
- Frank Koch, Two books, An introduction for people with no real background knowledge and Administrative tasks. Available in German and English (only read the English version – even though I do read German). Worth a read – especially if you are new or still trying to get it. The latter covers a lot of the free add-ons you can get. The German shines through in some places in the English version, but I do not think that is too big a problem.
- Keith Hill, Effective Windows PowerShell, 50 pages. You should read this if you have some knowledge of PowerShell. It covers the most important topics and goes quite deep into output formatters and parsing modes. Even longtime users may learn a few tricks. This books was updated March 2009 with some PowerShell v2 information.
Happy reading!
Friday, March 27, 2009
MUI for Office Communicator 2007 R2 available on TechNet
The following languages are included in the MUI:
Arabic
Bulgarian
Catalan
Chinese - Simplified
Chinese - Traditional
Chinese Hong Kong
Croatian
Czech
Danish
Dutch
English
Estonian
Finnish
French
German
Greek
Hebrew
Hindi
Hungarian
Italian
Japanese
Korean
Latvian
Lithuanian
Norwegian
Polish
Portuguese (Portugal)
Portuguese (Brazil)
Romanian
Russian
Serbian
Slovak
Slovenian
Spanish
Swedish
Thai
Turkish
Ukrainian
Get it here: http://www.microsoft.com/downloads/details.aspx?FamilyID=E7871DCD-8173-4866-A0C2-AF8659092ACC&displaylang=en
Thursday, March 26, 2009
Office Communications Server 2007 R2 Management Pack for System Center OpsMgr 2007 SP1
Get it here:
http://www.microsoft.com/downloads/details.aspx?FamilyID=0FCA3752-76D4-42F3-9241-A663E40C1E2C&displaylang=en
Wednesday, March 25, 2009
Get-OpenFile
One of the many nice things about PowerShell it that you can use the existing utilities you’ve got and you love. And then you can enrich them using PowerShell. You do this best by converting the output to objects – which you then can use down the pipeline.
One such example is here. Handle.exe (sysinternals.com) returns open files (and other handles). If you wrap that with a script, you can convert the output to objects and then manipulation is so easy.
Here is Get-Openfile.ps1
param($fileFilter=$(throw "Filter must be specified"))
handle $fileFilter | foreach{
if ($_ -match '^(?<program>\S*)\s*pid: (?<pid>\d*)\s*(?<handle>[\da-z]*):\s*(?<file>(\\\\)|([a-z]:).*)') {
$matches | select @{n="Path";e={$_.file}},@{n="Handle";e={$_.handle}},@{n="Pid";e={$_.pid}},@{n="Program";e={$_.program}}
}
}
Handle must be found via $env:path or an alias. Note the use of –match and $matches and how a regex is used to match the output and easily pick up the relevant parts of the output using names. One advice: Learn regex!
An example
PS C:\Windows\PolicyDefinitions> get-openfile er.exe
Path Handle Pid Program
---- ------ --- -------
C:\Windows\System32\en-US\... 38 7004 SearchIndexer.exe
C:\Windows\en-US\explorer.... 38 5764 explorer.exe
C:\Windows\SysWOW64\en-US\... 50 8484 explorer.exe
I originally called the Path property for File, but to bind the value automatically (in the pipeline), I renamed it to path.
This is nice -
PS> get-openfile er.exe | dir
Directory: C:\Windows\System32\en-US
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 27-05-2008 09:17 7680 SearchIndexer.exe.mui
Directory: C:\Windows\en-US
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 02-11-2006 16:12 27136 explorer.exe.mui
Directory: C:\Windows\SysWOW64\en-US
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 02-11-2006 16:12 36864 explorer.exe.mui
And this is just as nice -
PS> get-openfile er.exe | gps
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
1554 33 178276 107420 622 863,72 7004 SearchIndexer
957 87 74504 82528 356 465,01 5764 explorer
513 32 28768 34044 203 28,27 8484 explorer
I use the method in Get-OpenFile a lot as that provides many advantages.
PS. You must be administrator to run handle. Get-OpenFile simply does not return any objects if you are not an admin. Handle.exe does not set $? or $lastexitcode, so checking for the condition is not easy.
PS2. Handle.exe can also display the user name and close handles (Remove-Openfile?). It is left to the reader to implement that. Handle.exe does not display files opened across the network. –a can do that, but the path is a strange \Device\Mup path, so it is excluded.
Strange Select-Object Behavior in PowerShell V2 CTP3
In PowerShell v1, the rules are as follows -
- Select-Object used with –first or –last do not change the object type of the objects passing through
- Select-Object selecting properties or adding changes the object type to PSCustomObject
Proof -
PS> gps -id $pid | Get-Type # Normal
System.Diagnostics.Process
PS> gps -id $pid | select name,ws | Get-Type # PSCustomObject
System.Management.Automation.PSCustomObject
PS> gps -id $pid | select name,ws | select | Get-Type # PSCustomObject
System.Management.Automation.PSCustomObject
PS> gps -id $pid | select * | Get-Type # Normal (errors are left out)
System.Management.Automation.PSCustomObject
PS> gps -id $pid | select | Get-Type # Normal
System.Diagnostics.Process
In PowerShell V2 CTP3 the rules seem to be -
- Select-Object used with –first or –last works as in V1
- Select-Object, selecting properties or adding properties, creates a new type called Selected.<originaltype>
- Select-Object resulting in a Selected.<type> will be turned into a Selected.System.Management.Automation.PSCustomObject! Very strange and very problematic in real-life use
Examples, showing it -
PS> gps -id $pid | Get-Type # normal
System.Diagnostics.Process
PS> gps -id $pid | Select name,ws | Get-Type # Selected.<type>
Selected.System.Diagnostics.Process
PS> gps -id $pid | Select name,ws | Select | Get-Type # Selected...PSCustomObject
Selected.System.Management.Automation.PSCustomObject
PS> gps -id $pid | select | Get-Type # normal
System.Diagnostics.Process
PS> gps -id $pid | select | select | Get-Type # normal
System.Diagnostics.Process
PS> gps -id $pid | select -f 1| select | Get-Type # normal
System.Diagnostics.Process
PS>
PS. Get-Type is not a built-in, but this function -
function Get-Type($inputObject) {
process { if ($_ -is [object]) {$_.PSTypeNames[0] } }
end { if ($inputObject -is [object]) { $inputObject.PSTypeNames[0] } }
}
PowerShell V2 CTP3 – Compatibility Problem - $MyInvocation
In PowerShell v1, you can use $MyInvocation.invocationname to test whether a script was dot-sourced or not.
This works in V1
if ($myinvocation.invocationname -ne ".") {
throw "Script should be dot-sourced to make this work"
}
but it not work in V2, and I cannot find a work-around :(
PS> '"invocation=" + $myinvocation.invocationname' | sc $env:temp\test.ps1
PS> &$env:temp\test.ps1
invocation=C:\Users\po\AppData\Local\Temp\test.ps1
PS> . $env:temp\test.ps1
invocation=C:\Users\po\AppData\Local\Temp\test.ps1
PS> # does it work when an alias is used?
PS> new-alias test $env:temp\test.ps1
PS> test
invocation=test
PS> . test
invocation=test
Update: Posted the problem on connect. MS has already closed my report with a 'fixed', so let's hope that is the case.
Monday, March 23, 2009
ILM “2” will ship in Q1 2010
According to my colleague, Risto Pedersen. He heard it at the keynote at TEC 2009 in Las Vegas.
Wednesday, March 18, 2009
Jeffrey Snover - Distinguished Engineer
Jeffrey, the father of PowerShell, got appointed Distinguished Engineer - well deserved. Read more here.