Hot to use PowerShell to manage System Center Configuration Manager

The easiest way is by launching the Configuration Manager console. In the upper left corner, there’s a blue rectangle. Click the white arrow in the blue rectangle, and choose Connect via Windows PowerShell.


Now, you need to import the Configuration Manager module by using the Windows PowerShell Import-Module cmdlet. To import the Configuration Manager module, you will have to specify the path to the Configuration Manager module or change to the directory that contains the module. Here, we’re going to change to the module’s directory.

PS C:\>

PS C:\> CD ‘C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager’

PS C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager>

Then import the module;

Import-Module .\ConfigurationManager.psd1

To run the Configuration Manager cmdlets, you need to switch the path to the Configuration Manager site.

PS C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager>CD MSN

MSN – is my site code


Confirm that the Configuration Manager module has been loaded by using the cmdlet below;

PS MSN:\> Get-CMSite

BuildNumber : 7958

Features : 0000000000000000000000000000000000000000000000000000000000000000 InstallDir : C:\Program Files\Microsoft Configuration Manager

Mode : 0

ReportingSiteCode :

RequestedStatus : 110

ServerName :

SiteCode : MSN

SiteName : MSN pri site

Status : 1

TimeZoneInfo : 000001E0 0000 000B 0000 0001 0002 0000 0000 0000 00000000 0000 0003 0000 0002 0002 0000 0000 0000 

Type : 2

Version : 5.00.7958.1000


Powershell special characters

When you are using Powershell, it really helps if you use special characters to write your own scripts or interpret someone else’s scripts. Some of them are really common and get used very often….

# Hash – Single line comment


#This script is for ....
#This variable is to ...


$ Dollar sign – is used to declare a variable

$ComputerName = "Server1"
$password = "p@sw0rd"


| Pipeline- Executes the left side and with  the output feeds to the right


Get-Process | Select -first 10


% Percentage – Short for “FOREACH”


% ($Server in $Servers) { Write-Host $_}


? Question Mark – Short for “Where”


Get-process | ? {$ -like 'win*' -and $_.status -eq 'Running'}


@ () – Declares an array


$Servers = @ ("server1", "server2", "server3")


@ {} – Declares an hash table


$servers = @{"server1" = "Dell";
             "server2" = "HP";
             "server3" = "Nutanix"}


------------------------------------ OR

$params = @{};
$params['class'] = 'Win32_DiskDrive';
$params['filter'] = 'size=256052966400'; #find a drive which is 256GB in size
Get-WmiObject @params
Get-WmiObject -Class 'Win32_DiskDrive' -Filter 'size=256052966400'


& Ampersand – Executes strings as commandlets


& "Get-Scheduledjob"


! Exclamation – Short for “not”

$serverName = $null;
if(!$serverName) { Write-Host '$a is null' }


:: Double colon – Reference static member of a class. The class name must be enclosed in square brackets.

[string]::Equals = ("Computers", "COMPUTERS")
False # this will compare these two strings and returns false




PowerShell Script Monitors Security Logs and Sends Email Alerts

function Get-ADAuditLogsv2{

Param ($from = “abc@domain.local”,
$servers = (“DCVM01”),
$eventids = @(1076,1039),
$date = ((Get-Date).AddMinutes(-60))

$ErrorActionPreference= ‘silentlycontinue’
foreach ($server in $servers){
foreach ($eventid in $eventids) {

$events = Get-WinEvent -FilterHashtable @{logname=’security’;id=$eventid;StartTime=$date} -ComputerName $server
if ($events -ne $null){
foreach ($event in $events){
$eventsubject=$eventsubject.replace(“`n”, “”)
$eventsubject=$eventsubject.replace(“`r”, “”)
$body = @($timecreated,$eventmessage )| Out-String
$subject= “Event ID” + ” ” + $eventid + ” ” + $eventsubject
Send-MailMessage -Body $body -From $from -SmtpServer $smtpserver -Subject $subject -To $to


Get-Date | Out-File c:\errorlog.txt -Append -Force
$Error | Out-File c:\errorlog.txt -Append -Force

Monitoring Cluster Shared Volume – PowerShell

I have found this but haven't tested yet. I will tweak and use it soon.
#Cluster Shared Volume Free Disk Space
#Emails results of CSV free space on CLUSTER1
#Created 03-08-2011

#Import Failover Cluster PowerShell Module--------------------------------------------------------
Import-Module FailoverClusters

#Begin customization-------------------------
$SmtpServer = "" #Enter FQDN of SMTP server
$SmtpFrom = "CSV Status <>" #Enter sender email address
$SmtpTo = "" #Enter one or more recipient addresses in an array ("","")
$SmtpSubject = "CLUSTER1 CSV Free Disk Space Report" #Enter subject of message
#End customization---------------------------

#Get Cluster Shared Volume details and put into array. Convert results from bytes into gigabytes.
$objs = @()

$csvs = Get-ClusterSharedVolume
foreach ( $csv in $csvs )
   $csvinfos = $csv | select -Property Name -ExpandProperty SharedVolumeInfo
   foreach ( $csvinfo in $csvinfos )
      $obj = New-Object PSObject -Property @{
         Name        = $csv.Name
         Path        = $csvinfo.FriendlyVolumeName
         Size        = $csvinfo.Partition.Size
         FreeSpace   = $csvinfo.Partition.FreeSpace
         UsedSpace   = $csvinfo.Partition.UsedSpace
         PercentFree = $csvinfo.Partition.PercentFree
      $objs += $obj

#Original code
#$objs | ft -auto Name,Path,@{ Label = "Size(GB)" ; Expression = { "{0:N2}" -f ($_.Size/1024/1024/1024) } },@{ Label = "FreeSpace(GB)" ; Expression = { "{0:N2}" -f ($_.FreeSpace/1024/1024/1024) } },@{ Label = "UsedSpace(GB)" ; Expression = { "{0:N2}" -f ($_.UsedSpace/1024/1024/1024) } },@{ Label = "PercentFree" ; Expression = { "{0:N2}" -f ($_.PercentFree) } }

#Give a brief description of the output
$output = "The following shows the amount of free space available on the cluster shared volumes on DRSRVVSA."
#Modified code that puts results into a variable and formats results into list format
$output += $objs | fl Name,Path,@{ Label = "Size(GB)" ; Expression = { "{0:N2}" -f ($_.Size/1024/1024/1024) } },@{ Label = "FreeSpace(GB)" ; Expression = { "{0:N2}" -f ($_.FreeSpace/1024/1024/1024) } },@{ Label = "UsedSpace(GB)" ; Expression = { "{0:N2}" -f ($_.UsedSpace/1024/1024/1024) } },@{ Label = "PercentFree" ; Expression = { "{0:N2}" -f ($_.PercentFree) } } | out-string

#Email results
$SmtpClient = New-Object System.Net.Mail.SmtpClient
$MailMessage = New-Object System.Net.Mail.MailMessage
$SmtpClient.Host = $SmtpServer
$MailMessage.From = $SmtpFrom
Foreach ($address in $smtpTo)
$MailMessage.Subject = $SmtpSubject
#$MailMessage.IsBodyHTML = $true
$MailMessage.Body = $output


Get Last Reboot Date and Time – PowerShell

One of the most common questions asked when working with projects either for patching or testing or any other reason is when servers last rebooted. I have found the WMI class which will give us what we need.


So what can I get out of this class?

Get-WMIObject Win32_OperatingSystem | Get-Member

Get-CimInstance Win32_OperatingSystem | Get-Member

There is a difference we will see. Look at the definitions. This will reflect to their output.



and LastBootUpTime what we need and we need to pull this info out of here;

Get-WMIObject -ClassName win32_OperatingSystem | select csname, lastbootuptime

csname                 lastbootuptime
——                  ————–
USER-PC             20160707090526.982130+060


Get-CimInstance -ClassName win32_OperatingSystem | select csname, lastbootuptime

csname                  lastbootuptime
——                   ————–
USER-PC               7/7/2016 9:05:26 AM

So looks like we need to convert the time if you use Get-WMIObject

>$wmi = gwmi win32_operatingsystem


$LastBootUpTime = Gwmi Win32_OperatingSystem -Comp server01 | Select -Exp LastBootUpTime

>gwmi win32_operatingsystem | %{ $_.ConvertToDateTime($_.LastBootUpTime) }


>$BootTime = Invoke-Command -Cn server01, server02`
  -Command { (gwmi win32_operatingsystem).lastbootuptime }
>$BootTime | foreach { ([wmi]'').ConvertToDateTime($_) }

Why do you need to go through these conversions, just use Get-CimInstance...

>$BootTimes = Get-CimInstance -Cn server1, server2-Class Win32_OperatingSystem |
    Select PSComputerName, LastBootUpTime

>$BootTimes | Format-Table -AutoSize

PSComputerName LastBootUpTime       
-------------- --------------       
server1        8/18/2016 15:40:32 PM 
server2        8/19/2016 20:50:53 PM
 If you have got a few servers put them in a txt file  (serverlist.txt) and use;

$compname = Get-Content -Path C:\serverlist.txt
foreach ($comp in $compname) {
    Get-WmiObject win32_operatingsystem -ComputerName $comp | '
select CSName, @{LABEL='LastBootUpTime';'



Getting PowerShell 5 Running on Windows 7 and Server 2008 R2

PowerShellMagazine - (wallpaper) - KEEP CALM.cdr

The two biggest features in PowerShell 5.0 are Windows PowerShell OneGet and a new module for managing layer 2 network switches. Other features include updates for Desired State Configuration (DSC), the PowerShell console, and the Integrated Scripting Environment (ISE).

OneGet is the PowerShell team’s answer to the complexity of application installation. By using the Chocolately repository, applications can be installed, updated, or removed with command line precision.OneGet can potentially let you automate complex application installations, simplify network shares, and make reinstallation much easier. Imagine creating a OneGet script that installs all of your favorite applications automatically.

Windows Server 2012 R2 introduced native management of layer 2 network switches. When you have Windows Server certified equipment, you can use SCVMM 2012 R2 to manage the hardware. There are times when you might need to manage equipment with a PowerShell script. WMF 5.0 introduces that ability.

The new module, Network Switch, contains 19 cmdlets that allow you to do the following in a CIM session:

  • Investigate the switch and available features with the Get-NetworkSwitchFeature cmdlet.
  • Configure specific switch features or enable/disable switch features.
  • Manage VLANs with the NetworkSwitchVLAN cmdlet set (Get, New, Disable, Enable, Remove, Set).
  • Save or restore switch configurations.

So what is needed for getting PowerShell 5.0 on a Windows 7 or Server 2008 R2?

  1. You must have SP1.  If you are using source media that does not have it slip-streamed then you’ll need to apply it before getting started.  Most cloud based VMs should have SP1 on Server 2008 already.
  2. You must have .NET 3.5.1 or later to install PowerShell 4.  However, the PowerShell 4 installer does not block you if you don’t have it.  It successfully installs and then when you reboot you are still on your previous version (2 or 3).  You have to uninstall the PowerShell 4 Windows Update and then install .NET 4.5.1 and then reinstall PowerShell 4.  If you use the quick config below – this is detected for you and you are instructed to issue a chocolatey command to easily pull .NET 4.5.1 onto your system.
  3. You must first install PowerShell / Windows Management Framework WMF 4 before you can install PowerShell / WMF 5.  This is an interim dependency that the PowerShell team is planning to eliminate for the production release.  However if you try to install PowerShell 5 without 4 present, you just get a standard Windows Update WUSA error “This Update is not applicable to your system” (Error: 2149842967 or 0x80240017).  PowerShell 5 installs via one of the following windows updates:KB3055381, KB3055377 or KB2908075. The below quick config also detects this situation and installs PowerShell 4 and instructs you to reboot and re-run the quick config.
  4. Finally you can install PowerShell 5.


Creating a file share in AZURE

Microsoft Azure offers fully managed file shares in the cloud. Because Azure File Storage exposes file shares using the Server Message Block 3.0 (SMB) protocol, the predominantly used file share protocol for existing on-premises applications, it simplifies moving your existing applications to the cloud, and because Azure File Storage allows applications to mount file shares from anywhere in the world, your on-premises applications can take advantage of cloud storage without change. Azure File Storage also implements REST API protocol, which enables you to develop modern applications that integrate with existing applications. And Microsoft Azure File Storage has got new features like; SMB 3.0 support, includes encryption and persistent handles, a new browser-based file explorer in the Azure portal,  Azure Storage Metrics for Azure File storage an also the ability to mount Azure File Storage file shares from outside of Azure datacenters.

So how to create a file share; (GUI or Powershell), let’s try Powershell…

Choose your storage account… We will need the name for our powershell cmdlets;


And then click on the storage account to go on CONFIGURE .


At the very bottom click on Manage Access Keys to get your key;


We are interested in the Primary Access Key, and click on the little file icon next to it to copy. This is the long key such as


Next is we need to run our Powershell cmdlets;

$storageaccount = “msenelstorage01

$storageaccount_key = “b8VW6dmfugxsrNyF/TkHO9lkA0vSPs4jEos0w+KWEBJzPC0OBFStObAuUwzNJWUkT8Qs5AdUJsHGUiCYqbcjSw==

$sharename = “Logs”

$storageaccount_context = New-AzureStorageContext $storageaccount $storageaccount_key

$create_share = New-AzureStorageShare $sharename -Context $storageaccount_context

And let’s run this….

PS C:\Users\murat.senel> $storageaccount = “msenelstorage01”

$storageaccount_key = “b8VW6dmfugxsrNyF/TkHO9lkA0123456789jEos0w+KWEBJzPCFStObAuUwzNJWUkT8Qs5AdUJsHGUiCYqbcjSw==”

$sharename = “logs”

$storageaccount_context = New-AzureStorageContext $storageaccount $storageaccount_key

$create_share = New-AzureStorageShare $sharename -Context $storageaccount_context

PS C:\Users\murat.senel>

In the storage account, you can see the URL for file storage;


Now we can only check this on the Preview Portal as GUI;

Go to the Portal;


Click on the storage account that you used;


Click on the Files >


There it is, our Logs file share created….

The second method might be easier if you don’t want to use Powershell…

You can basically go to the File Share tab and  on the top you will see New Share tab.


What else can we show with a file share ?

Lets’ create a directory (called Server001Logs) in the Logs share;

PS C:\Users\murat.senel> New-AzureStorageDirectory -Share $create_share -Path Server001Logs


Type                Length             Name                                                                                                                 —-                ——             —-                                                                                                                    DIR                                    Server001Logs

And upload a file in to that directory…

Set-AzureStorageFileContent -Share $create_share -Source C:\MyScripts\serverlist.txt -Path Server001Logs

Let’s check them on the Portal ….


Directory is there .. And our uploaded file is …… >


also there…. 😉