System Center, Automation, Powershell and other Thoughts

Archive for the ‘Automation’ Category

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:

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:


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

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

    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

.\tempfiles.ps1 -startpath D:\

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

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

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

.\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.
See Link for further description.


<a href=""></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)
Get-childitem $startpath -recurse | `
ForEach-Object {
 if (($_.attributes -band 0x100) -eq 0x100)
  foreach($ext in $extensions)
  if($_.extension.tolower() -eq $ext.tolower())
     $_.attributes = ($_.attributes -band 0xFEFF)
$count = @(Get-childitem $startpath -recurse | where-object { $_.attributes -band 0x100 }).count
"There are $count files affected in $startpath with seleted extensions: `"$extensions`""
"Path $startpath not found!"
 get-help .\tempfiles

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.

(Update) SCCM vNext and Powershell

A few weeks ago,
I have written about the question if there will be Powershell support in SCCM vNext.

On yesterday I had the chance to listen to a very interesting talk from Microsoft about the user centric software deployment and SCCM vNext.
There I had the chance to ask about the Powershell support in the next version.

The answer is:

The next version has support for the same WMI classes
as it has in SCCM 07.
And there will be new WMI classes for the new features.
Powershell support is there using WMI cmdlets.

And perhaps the SDK for vNext will have some little more infos about using the Powershell to manage SCCM.
Cmdlets are not planed at the moment.

So, for all of you want to learn how to automate SCCM,
go out and learn something about WMI.

Do you know Opalis?

In December 2009 Microsoft bought the leader in datacenter automation and his famous product “Opalis Integration Server”.

Using Opalis you can fully automate provisioning in your datacenters. For example, building up a Virtual Server without any interaction in just a few minutes or adding a new user to all your systems with just a single click.
All of these tasks are done using a little process. The processes are build using drag and drop.

Microsoft has now released a roadmap of the integration of Opalis into its System Center products.  Opalis - Roadmap As shown in the picture, the first step is to update the installer. At the moment it is a JBoss with several Java classes to download from all over the internet for get it up and running.
Next steps are to build adapters for known systems to natively support them. As a person from the technical support line claimed, it is will be available over software assurance in the late 2010. The release of vNext with fully integration into the System Center family is planned for 2011. More information will follow later on, perhaps after the MMS 2010.

For more information’s, see this sources also:

Opalis on Microsoft pathways

Blog: Opalis software availability and roadmap

Technet: Opalis

Search for a string in a bunch of files …

A colleague had a directory with a lot of log-files in. In these he wants to search for a string and get the filename and line number automatically.

So we made this simple code in Powershell:

$items = Get-item *.log 
Foreach($item in $items)
                $loc = $item.fullname; 
                $content = get-content $item
                $contentcount = $content.count

                For($i = 0;$i –lt $contentcount; $i++)
                               If($content[$i] –match $searchstring)

So he was happy.

A few days later he came around with a simpler one:

select-string -path "*.log" -pattern "$searchstring" -allmatches -simplematch

Add a computer variable using Powershell

Servers mostly run with fixed IP-Addresses. So a question was to automate the server deployment using SCCM that also adds a fixed IP-Address to the server.

While SCCM has the ability to add a fixed IP-Address, the thing to do the deployment automatically was to add the OSD-Variables to the computer object in SCCM.

This can be done using a simple Powershell script and the WMI-Classes brought with SCCM.

# Powershell V2 only (V1 has errors in WMI)
param([string]$computer = ".",[string]$smssite = "MND",[int]$ResourceID=-9999,[string]$variable,[string]$value)

if(($ResourceID -ne -9999) -and ($variable -ne "") -and ($value -ne ""))
$pc_class = [WmiClass]""
$pc_class.psbase.Path ="\\$computer\ROOT\SMS\SITE_$($smssite):SMS_MachineSettings"
$pc = $pc_class.createInstance()

$pc.ResourceID = $ResourceID
$pc.SourceSite = $smssite


$pc.MachineVariables = $pc.MachineVariables + [WmiClass]"\\$computer\ROOT\SMS\SITE_$($smssite):SMS_MachineVariable"

$machinevariables = $pc.MachineVariables 

$machinevariables[($machinevariables.count)-1].Name = $variable
$machinevariables[($machinevariables.count)-1].value = $value

$pc.MachineVariables = $machinevariables 


  "Variable set"
  "Error in setting variable"
  "Not enough arguments given."

Adding variables this way is very easy and the correct names can be found in the SCCM documentation (