SCAPaoT

System Center, Automation, Powershell and other Thoughts

Archive for the ‘Powershell’ Category

Power Shell Script failed to run – SCOM 2012 Beta

After installation of the actual version of SCOM 2012 beta, we encountered the following error:

Power Schell Script failed to run (see Screenshot)

Searching for the script, we stumbled over a new management pack called “Microsoft SystemCenter OperationsManager Summary Dashboard”

As part of this management pack, there are three discoveries that failed running its Powershell script.
So we extracted one of this scripts and found, that the error was trown by $mp.GetDisplayString($lang) while $lang is filled by the get-culture commandlet.

Execution of get-culture while logged in with the SCOM action account delivered:

LCID             Name             DisplayName
—-             —-             ———–
1031             de-DE            Deutsch (Deutschland)

So we changed the cultur of all system accounts to en-US and the error was gone.

Hopefully this error get fixed in the future being independend from the language, like the powershell already tries to be.
So only the if() case need to have a executionpreference set to continue for fixing the error permanantly.

A bug is reportet at connect.microsoft.com.

 

Orchestrator 2012 Beta Integration Pack for SCOM not working on SCOM 2012 Beta

The Integration Pack for System Center Operations Manager, released for Opalis 6.3 but also avaliable for System Center Orchestrator 2012 Beta does not work with System Center Operations Manager 2012 Beta.

It’s caused by a change inside the SDK.

You can see the error here:

So, I have to create my own activities / powershell scripts for creation of alert or setting maintainance in SCOM 2012 Beta.

DFSR: Powershell script for removing “temporary file” flag to replicate a file

At a customer we decided to remove the need of backing up files in the branches, so theres no need for the employees to switch tapes or usb drives.
To get all data backed up nevertheless, we implemented DFSR between the branches and the head quarter. In the head quarter the data are backed up.

A quick look in the DFSR reportings showed up, that there are files, that where not backed up.

With a little search in a famous serach engine, we stumbled throughwards that blog:
http://blogs.technet.com/b/askds/archive/2008/11/11/dfsr-does-not-replicate-temporary-files.aspx

At the customer, there are some scanning devices responsible to convert all paper mail into digital files. Those devices are generating its output directly on the file server.
All files generated that way do not loose the temporary file attribute after saving the file.

So we buidled a powershell script that run’s as scheduler to remove these flags on a daily base.

If you are interested in this on,

here you are:


<#

.SYNOPSIS
This script is for determing files with  "Temporary File" attribute set.

.DESCRIPTION
The script shows files where the "Temporary File"-attribute is set. Those files are not synchronised by Microsoft DFSR.
Also the script can remove the attribute, based on the file extension.
The common extensions are a set as default, but can be overridden by command.

.PARAMETER startpath
    Specifies the file path to start the search for files with "Temp File"-attribute set.

    Required?                    true
    Default value
    Accept pipeline input?       false

.PARAMETER RemoveTemp
    If this switch is used, the "Temp File"-attribute is removed from the file.

    Required?                    false
    Default value
    Accept pipeline input?       false
.PARAMETER extensions
    Specifies the file extensions that should be inspected.

    Required?                    false
    Default value   (".pdf",".xls",".doc",".docx",".xlsx",".ppt",".pptx",".bmp",".jpg")
    Accept pipeline input?       false

.PARAMETER countOlny
    If given, only the count of the affected file is shown.

    Required?                    false
    Default value  
    Accept pipeline input?       false

.EXAMPLE
.\tempfiles.ps1 -startpath D:\

This Example lists the files where the "Temp File"-attribute is set located on the hole D:\ - Drive

.EXAMPLE
.\tempfiles.ps1 -startpath D:\ -removeTemp

This Example lists the files where the "Temp File"-attribute is set and removes the "Temp File"-attribute.

.EXAMPLE
.\tempfiles.ps1 -startpath D:\ -removeTemp -extensions ".exe",".jpg"

This Example lists the files where the "Temp File"-attribute is set if the file extension is exe or jpg only.
.NOTES
See Link for further description.

.LINK

<a href="http://blogs.technet.com/b/askds/archive/2008/11/11/dfsr-does-not-replicate-temporary-files.aspx">http://blogs.technet.com/b/askds/archive/2008/11/11/dfsr-does-not-replicate-temporary-files.aspx</a>

#>

param([string]$startpath=(read-host "Start Pfad"),[switch]$removeTemp,[string[]]$extensions=(".pdf",".xls",".doc",".docx",".xlsx",".ppt",".pptx",".bmp",".jpg"),[switch]$countOnly)

if(!($startpath -eq ""))
{
if(test-path -path "$startpath" -ErrorAction SilentlyContinue)
{
if(!($countonly))
{
Get-childitem $startpath -recurse | `
ForEach-Object {
 if (($_.attributes -band 0x100) -eq 0x100)
 {
  
  foreach($ext in $extensions)
  {
  if($_.extension.tolower() -eq $ext.tolower())
   {
    $_.fullname
  
    if($removetemp)
    {
     $_.attributes = ($_.attributes -band 0xFEFF)
    }
   break
   }
  }
 }
}
}
else
{
$count = @(Get-childitem $startpath -recurse | where-object { $_.attributes -band 0x100 }).count
"There are $count files affected in $startpath with seleted extensions: `"$extensions`""
}
}
else
{
"Path $startpath not found!"
}
}
else
{
 get-help .\tempfiles
}

KMS MP: Idle Minutes Monitor Alert

A customer of mine had several “Idle Minutes Monitor Alert” raised by the Key Management Server MP.

The eventlog for KMS on the KMS Server stated, that there was an KMS request round about every 30 seconds.
So the error was definitiv a false positive.

The treshold for the monitor was default (480 minutes).

I inspected the monitor and saw in the configuration, that the last activity in KMS is stored in the operations manager.
These values are inserted through a scheduled discovery that runs every 15 minutes.

I exported the management pack and had a look on that discovery. There I found an VBS script that does a lot of WMI queries.

As the KMS Server is a Server 2008 R2, and there is a WMI Memory Leak on excessive usage of WMI, I installed the corresponding hotfix and the error was gone.
This hotfix is: KB981314 (http://support.microsoft.com/kb/981314)

Kind regards,

Benedikt

Failed Accessing Windows Event Log: Microsoft-Windows-BranchCache/Operational

I stumbled about the following warning at a customer:

The warning was thrown for several servers and claimed, that the special eventlog for the feature “branch cache” was not able to be read.
Inspecting the systems didn’t show up that the branch cache feature installed.
Also netsh branchcache show status brought up the message: “This command can only be executed when BranchCache is installed.”

The problem was, that branch cache was installed on the systems brought up a warning, but not needed anymore.
While they where installed and configured, SCOM has discovered the systems.
So I installed the brach cache feature again, set the branch cache to disabled using netsh and uninstalled branch cache feature.

After that I disabled the discovery rules shown in the screenshot below.

Next step was to remove the disabled discoveries from the database using the powershell.

remove-disabledmonitoringobject

After that, I removed the disable overrides.

So the warnings didn’t appear again.

‘MOM.scriptAPI’ does not return property bag in Powershell ISE

When implementing a new management pack for SCOM 2007 R2, most of the time I try to use Powershell instead of VBScript.
For the development I normally use notepad++, but since this wasn’t installed at customers’ I tried using the ISE.

After an hour of troubleshooting, I switched to the console host of Powershell, and the script was working as suspected.
The code that confused myself are only a few lines:


$api = new-object -comObject 'MOM.ScriptAPI'
$bag = $api.CreatePropertyBag()

$bag.AddValue("test","123")

$api.return($bag)

Running the code in the ISE returns: NOTHING

Running it in the normal console host, retruns the xml structure of the SCOM property bag as suspected.

So, using notepad++ and the consolehost for deployment of managment pack scripts is my recommended way at the moment…

Hashtable doesn’t contain a method ‘Ádd’

The powershell has a really nice implementation of a dictionary. It is called Hashtable and can be used to store pairs of keys and values.
Compared with the dictionary used in vbscript, it is really simple to use,
and I have used it several times befor. Till last friday:

There is a method called ‘Add’, really!
And running a get-member agains a hashtable shows at the first entry:

Name         MemberType      Definition
—-              ———-                 ———-
Add            Method                  System.Void Add(System.Object key, System.Object value)

So where the hell does this error come from.
I decided to make a set-psdebug -step in the powershell ISE.
Have a look what I’ve found:

Yes, you can trust your eyes, there is an acute accent on top of the A
Add -> Ádd

Ok, so where are my glasses:

As you can see, using the ISE with a Font Size of 12
and a sceen resolution of 1920 x 1200
makes it hard to see everything clear.

And I’m really glad, that this wasn’t a real bug to my favorite object hashtable.

Get the IPAddresses from all computers in your Active Directory

A colleague of mine asked, how to retrieve the IPs from all servers in an active directory quickly.
Here is the answer:

#build a directorysearcher with ldap filter to get only computers
#if only a single server should be determined, change the * in name=* to name=<servername> (without <>)
$ds = new-object system.directoryservices.directorysearcher("(&(objectcategory=computer)(name=*))")

#get the computernames only
$computers = @($ds.findall() | % { ([adsi]$_.path).properties['name'] })

#loop through the names and try collect the IPs using wmi and list them
foreach($c in $computers)
  {
Get-WmiObject -computer $c -query "select * from win32_networkadapterconfiguration" | where-object { $_.ipaddress.count -gt 0 } | foreach-object { "$($c): $($_.ipaddress)" }
  }

Have fun.

Documentation made easy – Convert Problem Step Recorder File to HTML

Since Windows 7 and Server 2008 the build in tool “Problem Step Recorder” can make screenshots automatically on every click that is made. It is perfect for building installation howto’s or any other kind of documentation. Yes, there are more powerfull tools on the market, but hey, its for free… 
Only problem is, the files that are delivered as zipped MHT-Files only. So only browsers can show them. You are not able to import them for editing directly into Microsoft Word.

So I decided to build a little parser script in Powershell that converts the mht files from psr.exe into its html-files and jpeg’s.

This script takes the filepath of the zipfile or the unzipped mht file and extracts the hmtl, css, and jpeg’s into a subfolder:

param($file=$(read-host "filename of psr-zip or psr-mht file? "))

function writefile($dir, $fname, $text)
{
    $text | out-file -append $dir\$fname -Encoding "default"
}

function convertJPG($dir)
{

$jpgfiles = get-item $dir\*.jpeg.txt
foreach($jpg in $jpgfiles)
    {
        $filename = $jpg.name.tostring()

        "$filename -> $($filename.substring(0,$filename.length-4))"

        [System.Convert]::FromBase64String((Get-Content $jpg -readcount 0)) | set-content -Encoding Byte "$dir\$($filename.substring(0,$filename.length-4))"
        remove-item $dir\$filename -force
    }   
}

function extractPSR($zipfile, $destfolder)
{
 $shellApplication = new-object -com shell.application
 $zip = $shellApplication.Namespace($zipfile)
 $dest = $shellApplication.Namespace($destfolder)
 $dest.copyhere($zip.Items())
}
if(test-path $file)
{
$file = get-item $file

$folder = (get-date -Format "yyyyMMddHHmmss").tostring()
$folderObject = new-item $folder -type directory -force
$filename = ""

if($file.name.tostring().tolower().endswith(".zip"))
{
 $unzipdest = "$($folderobject.fullname.tostring())\temp"
 new-item $unzipdest -type directory -force | out-null
 extractPSR $file.fullname $unzipdest
 $psrfile = get-item "$unzipdest\*.mht"
}
else
{
 $psrfiles = $file
}

$content = get-content $psrfile

"Start: creating files in folder $pwd\$folder"

foreach($line in $content)
{
  switch -wildcard ($line)
  {
    "Content-Location: *"
    {
        #$line
        $filename = $line.split(":")[1].trim()
         if($filename.tolower().endswith(".jpeg"))
         {
            "writing: $filename.txt"
         }
         else
         {
            "writing: $filename"
         }

        break;
    }
    "--=_NextPart_*" { break; }

    "Content-Type: *" { break; }

    "Content-Transfer-Encoding: base64" { break; }

    default
    {
        if($filename -ne "")
        {
            if($filename.tolower().endswith(".jpeg"))
            {
                if($line -ne "")
                {
                    writefile $folder "$filename.txt" $line
                }
            }
            else
            {

                writefile $folder $filename $line
            }
        }
        break
    }

  }

}
"Finished: Creating files"
"Start: converting pictures from text to JPG"

convertJPG $folder
"Finished: converting pictures"

$yesno = read-host "Open containing folder? [y] "

if($yesno -eq "" -or $yesno.tolower() -eq "y")
{
    &explorer.exe $pwd\$folder
}
}
else
{
    "ERROR: $pwd\$file not found"
}

Next thougts are to convert it into a standard documentation directly or crop the slideshow of.

But these are plans for the future,
as well as adding some more comments to the code ;-)

Update

As there are several errors with the linefeeds while copying the source code, here you can download it as a .zip-File

psr.zip

Powershell: return is also an object…

I’m currently working on automation of SCCM software updates using Powershell.

I spend a lot of time on the following extremly simple task.
1. a function creates a list with updates
2. the same function returns the .count of the array of updates
3. the return value is added to an global variable of type Int32

And: Baaaahm -> System.Object[] can not be converted into System.Int32

Where the hell is the System.Object[] coming from? The return was an Int32!

See your self:

function returnTest
{
1..30
$array = 1..30
 return $array.count
 }

returnTest.gettype()

After I regocognized this behavoir of retrun, I found a very good blog about that:
http://keithhill.spaces.live.com/blog/cns!5A8D2641E0963A97!811.entry

So, make sure to throw away everything expect the return value with [void] or pipe to out-null.

As an alternativ, make sure return is the last command in the function.
So you can grab the value you expected from
$retrunvalue[$returnvalue.length-1] …