PoshCode Logo PowerShell Code Repository

Get-ADGroupModifications by Jan Egil Ring 7 years ago
embed code: <script type="text/javascript" src="http://PoshCode.org/embed/1810"></script>download | new post

The Get-ADGroupModificationsReport script, which were posted on http://poshcode.org/1402, are now enhanced in due to performance by storing each domain controllers security eventlog in a variable

  1. ###########################################################################"
  2. #
  3. # NAME: Get-ADGroupModificationsReport.ps1
  4. #
  5. # AUTHOR: Jan Egil Ring
  6. # EMAIL: jan.egil.ring@powershell.no
  7. #
  8. # COMMENT: Generates a HTML-report of Active Directory group membership modifications (addings and deletions).
  9. #          Specify a valid path on line 211 to store the report.
  10. #          For more details, see the following blog-post:
  11. #          http://blog.powershell.no/2009/10/11/active-directory-group-membership-modifications-report
  12. #
  13. # You have a royalty-free right to use, modify, reproduce, and
  14. # distribute this script file in any way you find useful, provided that
  15. # you agree that the creator, owner above has no warranty, obligations,
  16. # or liability for such use.
  17. #
  18. # VERSION HISTORY:
  19. # 1.0 11.10.2009 - Initial release
  20. # 1.1 29.04.2010 - Enhanced the script performance by storing each domain controllers security eventlog in a variable
  21. #
  22. ###########################################################################"
  23.  
  24. #Requires -Version 2.0
  25.  
  26.  
  27. function Get-CustomHTML ($Header){
  28. $Report = @"
  29. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http`://www.w3.org/TR/html4/frameset.dtd">
  30. <html><head><title>$($Header)</title>
  31. <META http-equiv=Content-Type content='text/html; charset=windows-1252'>
  32.  
  33. <meta name="save" content="history">
  34.  
  35. <style type="text/css">
  36. DIV .expando {DISPLAY: block; FONT-WEIGHT: normal; FONT-SIZE: 10pt; RIGHT: 8px; COLOR: #ffffff; FONT-FAMILY: Tahoma; POSITION: absolute; TEXT-DECORATION: underline}
  37. TABLE {TABLE-LAYOUT: fixed; FONT-SIZE: 100%; WIDTH: 100%}
  38. *{margin:0}
  39. .dspcont { BORDER-RIGHT: #bbbbbb 1px solid; BORDER-TOP: #bbbbbb 1px solid; PADDING-LEFT: 16px; FONT-SIZE: 8pt;MARGIN-BOTTOM: -1px; PADDING-BOTTOM: 5px; MARGIN-LEFT: 0px; BORDER-LEFT: #bbbbbb 1px solid; WIDTH: 95%; COLOR: #000000; MARGIN-RIGHT: 0px; PADDING-TOP: 4px; BORDER-BOTTOM: #bbbbbb 1px solid; FONT-FAMILY: Tahoma; POSITION: relative; BACKGROUND-COLOR: #f9f9f9}
  40. .filler {BORDER-RIGHT: medium none; BORDER-TOP: medium none; DISPLAY: block; BACKGROUND: none transparent scroll repeat 0% 0%; MARGIN-BOTTOM: -1px; FONT: 100%/8px Tahoma; MARGIN-LEFT: 43px; BORDER-LEFT: medium none; COLOR: #ffffff; MARGIN-RIGHT: 0px; PADDING-TOP: 4px; BORDER-BOTTOM: medium none; POSITION: relative}
  41. .save{behavior:url(#default#savehistory);}
  42. .dspcont1{ display:none}
  43. a.dsphead0 {BORDER-RIGHT: #bbbbbb 1px solid; PADDING-RIGHT: 5em; BORDER-TOP: #bbbbbb 1px solid; DISPLAY: block; PADDING-LEFT: 5px; FONT-WEIGHT: bold; FONT-SIZE: 8pt; MARGIN-BOTTOM: -1px; MARGIN-LEFT: 0px; BORDER-LEFT: #bbbbbb 1px solid; CURSOR: hand; COLOR: #FFFFFF; MARGIN-RIGHT: 0px; PADDING-TOP: 4px; BORDER-BOTTOM: #bbbbbb 1px solid; FONT-FAMILY: Tahoma; POSITION: relative; HEIGHT: 2.25em; WIDTH: 95%; BACKGROUND-COLOR: #cc0000}
  44. a.dsphead1 {BORDER-RIGHT: #bbbbbb 1px solid; PADDING-RIGHT: 5em; BORDER-TOP: #bbbbbb 1px solid; DISPLAY: block; PADDING-LEFT: 5px; FONT-WEIGHT: bold; FONT-SIZE: 8pt; MARGIN-BOTTOM: -1px; MARGIN-LEFT: 0px; BORDER-LEFT: #bbbbbb 1px solid; CURSOR: hand; COLOR: #ffffff; MARGIN-RIGHT: 0px; PADDING-TOP: 4px; BORDER-BOTTOM: #bbbbbb 1px solid; FONT-FAMILY: Tahoma; POSITION: relative; HEIGHT: 2.25em; WIDTH: 95%; BACKGROUND-COLOR: #7BA7C7}
  45. a.dsphead2 {BORDER-RIGHT: #bbbbbb 1px solid; PADDING-RIGHT: 5em; BORDER-TOP: #bbbbbb 1px solid; DISPLAY: block; PADDING-LEFT: 5px; FONT-WEIGHT: bold; FONT-SIZE: 8pt; MARGIN-BOTTOM: -1px; MARGIN-LEFT: 0px; BORDER-LEFT: #bbbbbb 1px solid; CURSOR: hand; COLOR: #ffffff; MARGIN-RIGHT: 0px; PADDING-TOP: 4px; BORDER-BOTTOM: #bbbbbb 1px solid; FONT-FAMILY: Tahoma; POSITION: relative; HEIGHT: 2.25em; WIDTH: 95%; BACKGROUND-COLOR: #A5A5A5}
  46. a.dsphead1 span.dspchar{font-family:monospace;font-weight:normal;}
  47. td {VERTICAL-ALIGN: TOP; FONT-FAMILY: Tahoma}
  48. th {VERTICAL-ALIGN: TOP; COLOR: #cc0000; TEXT-ALIGN: left}
  49. BODY {margin-left: 4pt}
  50. BODY {margin-right: 4pt}
  51. BODY {margin-top: 6pt}
  52. </style>
  53. </head>
  54. <body>
  55. <b><font face="Arial" size="5">$($Header)</font></b><hr size="8" color="#cc0000">
  56. <font face="Arial" size="1"><b>Generated on $($ENV:Computername)</b></font><br>
  57. <font face="Arial" size="1">Report created on $(Get-Date)</font>
  58. <div class="filler"></div>
  59. <div class="filler"></div>
  60. <div class="filler"></div>
  61. <div class="save">
  62. "@
  63. return $Report
  64. }
  65.  
  66. function Get-CustomHeader0 ($Title){
  67. $Report = @"
  68.                 <h1><a class="dsphead0">$($Title)</a></h1>
  69.         <div class="filler"></div>
  70. "@
  71. return $Report
  72. }
  73.  
  74. function Get-CustomHeader ($Num, $Title){
  75. $Report = @"
  76.         <h2><a class="dsphead$($Num)">
  77.         $($Title)</a></h2>
  78.         <div class="dspcont">
  79. "@
  80. return $Report
  81. }
  82.  
  83. function Get-CustomHeaderClose{
  84.  
  85.         $Report = @"
  86.                 </DIV>
  87.                 <div class="filler"></div>
  88. "@
  89. return $Report
  90. }
  91.  
  92. function Get-CustomHeader0Close{
  93.  
  94.         $Report = @"
  95. </DIV>
  96. "@
  97. return $Report
  98. }
  99.  
  100. function Get-CustomHTMLClose{
  101.  
  102.         $Report = @"
  103. </div>
  104.  
  105. </body>
  106. </html>
  107. "@
  108. return $Report
  109. }
  110.  
  111. function Get-HTMLTable {
  112.         param([array]$Content)
  113.         $HTMLTable = $Content | ConvertTo-Html
  114.         $HTMLTable = $HTMLTable -replace "<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0 Strict//EN""  ""http`://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"">", ""
  115.         $HTMLTable = $HTMLTable -replace "<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.01//EN""  ""http`://www.w3.org/TR/html4/strict.dtd"">", ""
  116.         $HTMLTable = $HTMLTable -replace "<html xmlns=""http`://www.w3.org/1999/xhtml"">", ""
  117.         $HTMLTable = $HTMLTable -replace '<html>', ""
  118.         $HTMLTable = $HTMLTable -replace '<head>', ""
  119.         $HTMLTable = $HTMLTable -replace '<title>HTML TABLE</title>', ""
  120.         $HTMLTable = $HTMLTable -replace '</head><body>', ""
  121.         $HTMLTable = $HTMLTable -replace '</body></html>', ""
  122.         return $HTMLTable
  123. }
  124.  
  125. function Get-HTMLDetail ($Heading, $Detail){
  126. $Report = @"
  127. <TABLE>
  128.         <tr>
  129.         <th width='25%'><b>$Heading</b></font></th>
  130.         <td width='75%'>$($Detail)</td>
  131.         </tr>
  132. </TABLE>
  133. "@
  134. return $Report
  135. }
  136.  
  137. #Initialize array for domain controllers in the current domain
  138. $domaincontrollers = @()
  139.  
  140. #Get current domain
  141. $dom = [System.DirectoryServices.ActiveDirectory.Domain]::getcurrentdomain()
  142.  
  143. #Get domain controllers in the current domain and add them to the $domain controllers array
  144. $dom.DomainControllers | select Name | ForEach-Object {$domaincontrollers += $_.name}
  145.  
  146.  
  147.  
  148. $MyReport = Get-CustomHTML "Active Directory Group Modifications - Daily Report"
  149.         $MyReport += Get-CustomHeader0 ("$domaincontroller")
  150.                
  151.                 # ---- General Summary Info ----
  152.                 $MyReport += Get-CustomHeader "1" "General Details"
  153.                         $MyReport += Get-HTMLDetail "Domain name:" $dom
  154.                         $MyReport += Get-HTMLDetail "Number of Domain Controllers:" $domaincontrollers.count
  155.                 $MyReport += Get-CustomHeaderClose
  156.  
  157. foreach ($domaincontroller in $domaincontrollers){
  158.  
  159. $eventlog = Get-EventLog -LogName ‘Security’ -ComputerName $domaincontroller -After ((Get-Date).AddDays(-1))
  160.  
  161. # ---- Members added to Domain Local Groups ----
  162.                $MyReport += Get-CustomHeader "1" "Members added to Domain Local Groups on domaincontroller $domaincontroller"
  163.                        $MyReport += Get-HTMLTable ($eventlog | Where-Object {$_.EventID -eq "636" -or $_.EventID -eq "4732"} | select TimeGenerated,Message  )
  164.                $MyReport += Get-CustomHeaderClose
  165.  
  166. $MyReport += Get-CustomHeader0Close
  167. $MyReport += Get-CustomHTMLClose
  168.  
  169. # ---- Members removed from Domain Local Groups ----
  170.                $MyReport += Get-CustomHeader "1" "Members removed from Domain Local Groups on domaincontroller $domaincontroller"
  171.                        $MyReport += Get-HTMLTable ($eventlog | Where-Object {$_.EventID -eq "637" -or $_.EventID -eq "4733"} | select TimeGenerated,Message  )
  172.                $MyReport += Get-CustomHeaderClose
  173.  
  174. $MyReport += Get-CustomHeader0Close
  175. $MyReport += Get-CustomHTMLClose
  176.  
  177. # ---- Members added to Global Groups ----
  178.                $MyReport += Get-CustomHeader "1" "Members added to Global Groups on domaincontroller $domaincontroller"
  179.                        $MyReport += Get-HTMLTable ($eventlog | Where-Object {$_.EventID -eq "632" -or $_.EventID -eq "4728"} | select TimeGenerated,Message  )
  180.                $MyReport += Get-CustomHeaderClose
  181.  
  182. $MyReport += Get-CustomHeader0Close
  183. $MyReport += Get-CustomHTMLClose
  184.  
  185. # ---- Members removed from Global Groups ----
  186.                $MyReport += Get-CustomHeader "1" "Members removed from Global Groups on domaincontroller $domaincontroller"
  187.                        $MyReport += Get-HTMLTable ($eventlog | Where-Object {$_.EventID -eq "633" -or $_.EventID -eq "4729"} | select TimeGenerated,Message  )
  188.                $MyReport += Get-CustomHeaderClose
  189.  
  190. $MyReport += Get-CustomHeader0Close
  191. $MyReport += Get-CustomHTMLClose
  192.  
  193. # ---- Members added to Universal Groups ----
  194.                $MyReport += Get-CustomHeader "1" "Members added to Universal Groups on domaincontroller $domaincontroller"
  195.                        $MyReport += Get-HTMLTable ($eventlog | Where-Object {$_.EventID -eq "660" -or $_.EventID -eq "4756"} | select TimeGenerated,Message  )
  196.                $MyReport += Get-CustomHeaderClose
  197.  
  198. $MyReport += Get-CustomHeader0Close
  199. $MyReport += Get-CustomHTMLClose
  200.  
  201. # ---- Members removed from Universal Groups ----
  202.                $MyReport += Get-CustomHeader "1" "Members removed from Universal Groups on domaincontroller $domaincontroller"
  203.                        $MyReport += Get-HTMLTable ($eventlog | Where-Object {$_.EventID -eq "661" -or $_.EventID -eq "4757"} | select TimeGenerated,Message  )
  204.                $MyReport += Get-CustomHeaderClose
  205.  
  206. $MyReport += Get-CustomHeader0Close
  207. $MyReport += Get-CustomHTMLClose
  208.  
  209. }
  210.  
  211. $Date = Get-Date
  212. $Filename = "C:\Temp\" + "DailyReport" + "_" + $Date.Day + "-" + $Date.Month + "-" + $Date.Year + ".htm"
  213. $MyReport | out-file -encoding ASCII -filepath $Filename

Submit a correction or amendment below (
click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:


Remember me