Tuesday 20 March 2018

Modify DPM protection groups in powershell

We have been backing up our workstations for a very long time, but one day it strike me, that our workflow, which consisted of shared checklist edited by two people, is kind of troublesome. Since I like to automate everything I can, I started to make this little script, which saves me a lot of work.

We administrate a few companies in our group, every one of them has its separate organizational unit in AD. When I created our DPM Protection Groups, I created it the same way, so every company has its Protection Group as well.

Script is supposed to get list of newly added workstations from specific organizational unit and add them to its Protection Group on DPM server.

# Import the DPM PowerShell module
#You can get installPath variable either from registry or set the specific local path.
#$installPath = (Get-ItemProperty -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft Data Protection Manager\Setup").UIInstallPath
$installPath = "C:\Program Files\Microsoft System Center 2012 R2\DPM\DPM\bin\"
$dpmModuleFullPath = $installPath + "Modules\DataProtectionManager\DataProtectionManager.psd1"
Import-Module $dpmModuleFullPath

#Variables
$DPMServer = "DPM_SERVER_FQDN"
$WorkingPath = "C:\Program Files\Microsoft System Center 2012 R2\DPM\DPM\bin"
$LogDirectory = "C:\Scripts\DPM\Logs\added\$Date\"
$MailRecipient = ""
$MailSubject = ""
$SMTPServer = ""
$MailSender = ""
#We have different AD containers for each company in our group. I use these names as protection group names as well, this comes very handy later in the script.
$Companies = "ORGANIZATIONAL_UNIT_A", "ORGANIZATIONAL_UNIT_B", "ORGANIZATIONAL_UNIT_C", "ORGANIZATIONAL_UNIT_D", "ORGANIZATIONAL_UNIT_E"

$Date = Get-Date -Format yyyy-MM-dd
#Script is supposed to run every week, so we just want to add computers from last few days and limit the amount of stations we work with on every run.
$Recently = [DateTime]::Today.AddDays(-8)

Set-Location -Path $WorkingPath
New-Item -ItemType Directory -Path $LogDirectory

#HTML header with some CSS
$HTMLbody_header = "
<!DOCTYPE html>
<html>
<head>
<style>
#os {
    font-size:10px;
    color: #9f9f9f;
}
th, td {
    border: 1px solid;
    border-color: #cccccc;
    padding: 15px;
    margin: 0px;
    border-spacing: 0px;
    font-weight: normal;
}
table {
    background-color: #fcfcfc;
    padding: 5px;
    margin: 0px;
    border-spacing: 0px;
}
body {
    font-family: Verdana, sans-serif;
    font-size:12px;
}
</style>
</head>
<body>"


#Start HTML body
$HTMLbody = "
<h3>New DPM backups.</h3>"


foreach ($Company in $Companies){
    #Get content from AD for every company.
    #DO NOT FORGET TO SPECIFY YOUR OWN PATH
    $Searchbase = 'OU=OU_NAME,OU=OU_NAME' + $Company + ',OU=OU_NAME,DC=DC_NAME,DC=DC_NAME'
    $List = Get-ADComputer -Filter 'WhenCreated -ge $recently' -Properties whenCreated -SearchBase $Searchbase
    $LogFile = $LogDirectory + $Company + ".txt" 
    $Computers = $List.Name 

    if ($Computers){
        #Define HTMLbody table
        $HTMLbody += "
        <h3>$Company</h3>
        <table>
        <tr style=""background-color:#f3f3f3"">
        <th align=Center >ComputerName</th>
        <th align=Center >Status</th>
        </tr>"

    }
    foreach ($Computer in $Computers){
        #Add content to HTMLbody table
        $HTMLbody += "
        <tr>
        <td align=left >$Computer</th>
        <td style=""background-color:#acfa58; color:#379510"" align=center >ADDED</th>
        </tr>"

        $Computer >> $LogFile

        #Modify Protection Group
        #Since our Companies and Protection Groups share the same name, we can use it to easily specify which protection group we want to edit depending on which Company's foreach cycle: "Where-Object {$_.FriendlyName.ToUpper() -eq $Company.ToUpper()}"
        #The first command gets all protection groups from the DPM server, and then stores these groups in the $pg variable. You cannot edit these protection groups.
        $pg = Get-ProtectionGroup -DPMServerName $DPMServer | Where-Object {$_.FriendlyName.ToUpper() -eq $Company.ToUpper()}
        #The second command gets the first protection group in the $pg array in editable mode, and then stores it in the $Modpg variable.
        $Modpg = Get-ModifiableProtectionGroup -ProtectionGroup $pg
        #The third command gets an array of protected and unprotected data on the production server, and then stores the array in the $ds variable.
        $ds = Get-DataSource -ComputerNames $Computer -DPMServerName $DPMServer
        #The fourth command adds that data source to the protection group stored in $ds.
        Add-ChildDataSource -ProtectionGroup $Modpg -ChildDataSource $ds
        #Commit changes.
        Set-ProtectionGroup -ProtectionGroup $Modpg
    }
    $HTMLbody += "
    </table>"

}
#HTML footer
$HTMLbody += "
</body>
</html>"


$HTMLmessage = $HTMLbody_header + $HTMLbody_info + $HTMLbody
Send-MailMessage -To "$MailRecipient" -Subject "$MailSubject" -SmtpServer "$SMTPServer" -From "$MailSender" -Body "$HTMLmessage" -BodyAsHtml

Mail output looks like this:

New DPM backups.

Company_A

ComputerName Status
Computer_1 ADDED

Company_B

ComputerName Status
Computer_2 ADDED

Company_C

ComputerName Status
Computer_3 ADDED