čtvrtek 30. dubna 2009

How to access LN data

Few months ago I started to use PowerShell for access to my Lotus Notes Inbox. It is pretty cool because I don't need to go to LN every time the mail arrives and can see it directly in my dearest Win application:



You see I modified my profile so the number in brackets means how many emails I have in Inbox. Alias she calls my function Show-Email and displays last email (default behaviour). In this article I'd like to show you basic idea. In the next one will show you how to do the work more automatically. Thanks @ye110wbeard for asking on Twitter - it kicks me to finally write the article :)

Whole work with Lotus Notes consists of following steps:
  • Connect to Lotus Notes session
  • Select Database
  • Select View
  • Go thru all documents inside loop
Connect to Lotus Notes Session
As COM is used for connection, New-Object is the way:

PS C:\> $session = New-Object -ComObject Lotus.NotesSession
PS C:\> $session.Initialize()
PS C:\> $session.NotesVersion
Release 6.5.3|September 14, 2004

OK, we are in, let's continue.

Open database and select View
You can connect to database located on the server or to local database. In case of local database, use empty string as first parameter of GetDatabase method.

PS C:\> $db = $session.GetDatabase('','names.nsf')
PS C:\> $db.Title
Moravec's Address Book
PS C:\> $view = $db.GetView('Contacts')
PS C:\> $view.Name
Contacts
PS C:\> $view.AllEntries.Count
215

You can see that I have 215 records in my Address book. I use AllEntries.Count every time I am downloading data from other (big) databases. I simply use the value in Write-Progress cmdlet so can see what's going on.

Grab data
Before you start do read records you have to know the names of items. Who is your best fried now? Of course Get-Member. Or you can go directly to LN database and check the fields manually via Document Properties.

PS C:\> $view.GetFirstDocument().Items | select Name | fw -col 4

Yupii - we are almost done:

PS C:\> $doc = $view.GetFirstDocument()
PS C:\> while ($doc -ne $null) {
$lastname = $doc.GetItemValue("LastName")
$firstname = $doc.GetItemValue("FirstName")
Write-Host "$firstname $lastname"
$doc = $view.GetNextDocument($doc)
}

You will see long list of names if you typed it correctly.

In this article I showed you how to easily connect to any LN database and read data from that db. I use the same technique for reading data from our company structure, converting it to objects and load it to PowerGUI for better work with the data.

Livemeeting: Windows PowerShell – úvod

Včera proběhl on-line seminář s názvem Windows PowerShell - úvod. Pod záštitou firmy Altairis byl přednášejícím Štěpán Bechyňský z Microsoftu.

Celá prezentace byla opravdu úvodem a neměla za cíl provést uživatele do hloubky PowerShellu. Jednotlivé části byly ukazovány i v konzoli PowerShellu, takže posluchači měli možnost vidět příkazy ze slidů naživo. Vzhledem k tomu, že se jednalo (pokud si dobře pamatuji) o první on-line vlaštovku nezbývá než doufat, že se dočkáme dalších pokračování. Prezentace měla některé slabší části, ale z mého pohledu převládlo nadšení, že jsme se konečně dočkali české verze. Ke stažení byl dostupný soubor s prezentací a ukázkovými soubory.

Celá prezentace bude po částech dostupná na MSTV.CZ.

středa 29. dubna 2009

Hej, mistře Šelíku!

V jednom ze starších vydání mistra Skriptíka padl následující dotaz: "V přihlašovacím skritpu potřebuji ověřit existenci souboru. Víš, jak na to?" Odpověď byla následující: "Jedna možnost je použít objekt FileSystem a metodu FileExists."

Pokud chcete řešení v PowerShellu, mohu doporučit přímo cmdlet Test-Path. Více o něm v dřívějším článku.
V případě, že chcete použít .NET, existuje třída System.IO.File a obsahuje metodu Exists. Použití je následující:

PS c:\> [System.IO.File]::Exists("c:\config.sys")
True

úterý 21. dubna 2009

PowerShell presentation

OK guys, it's here. As I promised here are slides and demo files from presentation for my colleagues.
  • Slides - I converted it to PDF and removed all company logos so somewhere it can looks strange.
  • Demo files used during presentation. Based on usage of specific technology there are short examples (VM) or really complex (ACL). Complex doesn't mean thousands of lines - we are in PowerShell :)
When I am doing presentation I use practical examples as much as I can. And I am talking a lot - ask my colleagues :) So sometimes you can feel like "out of the context" when looking only to presentation.

I found out that the most interesting part was setting of ACL. On the other hand I was compelled to slow down presentation when I talked about objects in PowerShell. My admin colleagues never tried any object oriented language so I saw on their faces they are "lost". After that I digressed a bit and tried to desbribed the idea of objects. Now I know that for next presentation (if presented for administrators) I have to redesign the slides.

As a conclusion I can say that it was fun. I felt that they were really interested and for the future I see that some of them can thing about PowerShell as about the tool which saves them a lot of work.

pátek 17. dubna 2009

Hej, mistře Šelíku!

Při pročítání posledního CZ TechNet zpravodaje mě napadlo zpracovat téma z komiksu Hej, mistře Skriptíku! v PowerShellu. TechNet Flash zpravodaj je dostupný na www.technetflash.cz (včetně starších čísel). Rozhodně jej doporučuji všem IT odborníkům.


Tentokrát budeme potřebovat PowerShell v2 (CTP3). Tato verze již obsahuje cmdlety pro práci s Windows Event Logy:

PS C:\Users\beta> Get-Command -noun EventLog | Select-Object Name
Clear-EventLog
Get-EventLog
Limit-EventLog
New-EventLog
Remove-EventLog
Show-EventLog
Write-EventLog

Mrkneme se na Write-EventLog. Ten má čtyři povinné parametry: LogName, Source, EventID, Message. Zkusme tedy něco zapsat do aplikačního logu:

Write-EventLog -LogName Application -source "Windows Error Reporting" -eventID 007 -Message "James Bond is cool!"

Výborně, stále tomu ale něco chybí. Většinou budete chtít zapisovat data z vašich programů. Pokud zkusite zápis ve tvaru:

Write-EventLog -LogName Application -source "Moje Aplikace" -eventID 007 -Message "James Bond is cool!"

PowerShell vám vrátí chybu jejíž část The source was not found vám oznámí, že toto nelze. Je to způsobené tím, že každý zdroj (Source), který zapisuje do Event Logu musí být předem zaregistrován (viz MSDN). Naštěstí exituje v PowerShellu cmdlet New-EventLog, který tuto službu udělá za vás. Následující seznam příkazů již tedy povede ke zdárnému konci (pro registraci zdroje musíte příkaz pustit s právy administrátora):

PS C:\> New-EventLog -LogName Application -Source "Moje Aplikace"
PS C:\> Write-EventLog -LogName Application -source "Moje Aplikace" -eventID 001 -Message "Ale ja jsem jednicka."

pátek 13. března 2009

smsDiagram - Draw your SMS hierarchy with one script

The Story
I am an administrator of big SMS hiearchy. Few times I reported to management how our infrastructure looks like. You know managers - they doesn't understand to objects, pipes and other funny parts of admin life. They are like children - likes pictures and graphs. So it's nice to show them infrastructure drawn in Visio. Till now I created it manually but after we merged few sites together it's not fun anymore (we have about 300 servers).

Maybe you recognized small analogy in the title of this post. When I saw an article written by Alan Renouf I knew that my future is bright. So thanks to Alan to kick me (Virtu-Al(ly) of course :)

The Script
Script itself is not so complicated. The biggest part is related to Visio (I use 2003 version) drawing. But there are some parts you might find useful for your own scripts.

Load hierachy from WMI
  1. $siteCode = (Get-WmiObject -ComputerName $server -Namespace root/sms `
  2. -Class SMS_ProviderLocation -Filter "ProviderForLocalSite='True'").SiteCode
  3. # SMS Namespace path
  4. $SMSWMINamespace = 'root/sms/site_'+$siteCode
  5. # List of children servers from SMS_Site class
  6. $servers = Get-WmiObject -ComputerName $server -Namespace $SMSWMINamespace -Class SMS_Site | `
  7. Select ReportingSiteCode, SiteCode, ServerName, Type | `
  8. Sort ReportingSiteCode, SiteCode
At lines 1-2 we have one-liner which connects to WMI of the site server (specified as parameter of the script) and find sitecode in SMS_ProviderLocation class. Then we connect to the SMS site namespace. We can load all necessary information from that namespace (lines 7-9) and save it in $servers object.

Text representation of SMS hierarchy
If you don't have Visio or just want quick overwiew you have two choices:
  1. Use standard SMS report (Sites by hierarchy with time of last site status update)
  2. Pass parameter $textInfo to smsDiagram script :)
Second option will display your hierarchy in this way:

PS C:\> ./smsDiagram.ps1 -server SMS01 -textInfo
CC0 (P)
  CZ0 (P)
    500
    HU0 (P)
      501
  ZZ0 (P)
    003
    004
    ZZ1 (P)

It's easy and fast - as fast as your connectivity to the site server. (P) means that the displayed server is Primary server.

Voila
And here is the nicest part of the script. It uses standard Visio Network template - Detailed Network Diagram. If you want to show infrastructure as Visio diagram just provide site server name as a parameter. In the diagram you can also see which server is Primary (db icon) and which is Secondary.

PS c:\> smsDiagram.ps1 -server SMS01



Now I have latest SMS hierarchy at my desk and it looks awesome :) Final document is saved in your My Documents folder, name is smsDiagram.vsd.

Notes
I didn't test the script against ConfigMgr. My "test lab" is not active now (to be honest - my NB where I ran it crashed before few days and I haven't time to rebuild it now).
No error codes checking now. Be sure you run the script as admin able to connect to WMI of site server.
Sometimes the Visio diagram is "ugly" - it fully depends on how the Visio handle objects creation. Hopefuly will find some solution but it's not a priority now.
Default text info shows site code. For next version I plan to add switch which tells what do you want to show as server description.
For the future versions of the script I also would like to add some more features - display server roles (MP, CAP, ...), customize output (shape names, connectors).
Source code is available at PoSh Code.

Please let me know if you find it useful or if you find some errors. Any feedback for improvement is welcome.

pondělí 9. března 2009

Looking for HResult

In one of the last Hey, Scripting Guy! article is described how to install updates and check it's result codes. I was really surprised when Scripting guys told me: "We can use calc.exe" - OMG why not use converting directly in PowerShell?

PS C:\> "0x{0:x}" -f [int] -2145124318
0x80240022

When I tried this I start thinking about the function which will do the conversion and shows also description of the result code.

  1. # Name : Get-HResult.ps1
  2. # Author: David "Makovec" Moravec
  3. # Web : http://www.powershell.cz
  4. # Email : powershell.cz@googlemail.com
  5. #
  6. # Description: Finds meaning of HResult
  7. #
  8. # Version: 0.1
  9. # History:
  10. # v0.1 - (add) basic functionality
  11. #
  12. # Usage: Get-HResult -2145124318
  13. #
  14. #################################################################
  15. function Get-HResult {
  16. param (
  17. $HResult,
  18. $url = 'http://technet.microsoft.com/en-us/library/cc720442.aspx'
  19. )
  20. $calc = "0x{0:x}" -f [int]$HResult
  21. $lookFor = $calc+'.*?tr'
  22. $wc = New-Object system.net.webclient
  23. $wc.DownloadString($url) -match $lookFor | Out-Null
  24. $tmp = $matches[0]
  25. $searchString = '(?<ResCode>'+$calc+').*\<p\>(?<ResStr>.+?)\<.*\<p\>(?<Description>.+?)\</p.+'
  26. $tmp -match $searchString | Out-Null
  27. Write-Host "HResult: " $HResult
  28. Write-Host "Result Code: " $matches.ResCode
  29. Write-Host "Result String: " $matches.ResStr
  30. Write-Host "Description: " $matches.Description
  31. } #function

By default script return results for Windows Update Agent and has no checking for errors. It has parameter for providing different URL but I didn't try any. Usage is following:

PS C:\> Get-HResult -2145124351
Result Code: 0x80240001
Result String: WU_E_NO_SERVICE
Description: Windows Update Agent was unable to provide the service.

Source code will be available at PoSh Code when I'll be able to open it, now have troubles with connectivity.