<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Manny Murguia's Blog</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/manny/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/manny/feed.xml</link>
    <description>Hoping to make IT life just a litte easier for us all!</description>
    <lastBuildDate>Wed, 17 Apr 2019 03:27:43 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Migrating GPO Links between Domains with PowerShell</title>
      <link>https://docs.microsoft.com/archive/blogs/manny/migrating-gpo-links-between-domains-with-powershell</link>
      <pubDate>Sat, 18 May 2013 05:10:00 GMT</pubDate>
      <dc:creator><![CDATA[Manny Murguia]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/manny/2013/05/18/migrating-gpo-links-between-domains-with-powershell/</guid>
      <description><![CDATA[By popular demand, I recently completed a script to migrate links between two domains. Like every...]]></description>
      <content:encoded><![CDATA[<p>By popular demand, I recently completed a script to migrate links between two domains. Like every script I write, it probably won't be without its&nbsp;bugs due to corner cases, but it will hopefully save everyone some time when it does work. That being said, please run tests before going to your production environment with it.</p>
<p>&nbsp;</p>
<p>This script is fairly straightforward and uses the Active Directory module for PowerShell. Here are some gotchas I came across during the creation and testing of this script:</p>
<p>&nbsp;</p>
<p>1. The OU structure and Site names must be the same between the source and destination domains. By default, the script logs an error at C:\GPOLinksLog.txt if a particular OU or Site does not exist. There are probably plenty of scripts in Internet land that can be used to duplicate OU structures and sites, so happy searching!</p>
<p>2. The script overwrites the "gPLink" attribute during the Import process. That means any already existing links on the particular OU or Site will be overwritten. For more information about the gPLink attribute and gpLinkOptions, see <a href="https://msdn.microsoft.com/en-us/library/cc232505.aspx">https://msdn.microsoft.com/en-us/library/cc232505.aspx</a></p>
<p>3. By now, you should have already completed the steps in my previous blog post: <a title="Bulk Import of Group Policy Objects between Different Domains with PowerShell" href="https://blogs.technet.com/b/manny/archive/2012/02/12/bulk-import-of-group-policy-objects-between-different-domains-with-powershell.aspx">Bulk Import of Group Policy Objects between Different Domains with PowerShell</a>. If GPO's with the same name between the source and destination domain do not exist, the script will not be very effective. You may also want the old WMI filters linked. Scripts for that process are&nbsp;located <a href="https://blogs.technet.com/b/manny/archive/2012/02/04/perform-a-full-export-and-import-of-wmi-filters-with-powershell.aspx">here</a> (for Exporting) and&nbsp;<a href="https://blogs.technet.com/b/manny/archive/2012/02/05/exporting-and-importing-wmi-filters-with-powershell-part-2-import.aspx">here</a>&nbsp;(for Importing).</p>
<p>4. If the Input option is used and a particular GPO does not exist, an error is logged in the LogFile location, but the script still links the other GPO's that do exist on particular object. If none of the GPO's linked to an object exist, no action is taken on that object,&nbsp;and an error is logged.</p>
<p>Now, let's see how easy the script is to use. There are three switches:</p>
<p>-OutputFile: This switch is used to export GPO Links from the source domain. The full path to the desired file should be specified (e.g. -OutputFile C:\temp\migratelinks.txt) otherwise a relative path to the file specified is used.</p>
<p>-InputFile: This switch is used to import GPO Links to the destination domain. The full path to the desired file should be specified (e.g. -InputFile C:\temp\migratelinks.txt) otherwise a relative path to the file specified is used.</p>
<p>-LogFile: This optional switch is used to specify a log file (e.g. -LogFile C:\temp\LogFile.txt). The default value is C:\GPOLinksLog.txt.</p>
<p>When specifying OutputFile or InputFile, at least one and only one of the two switches must be specified. Helpful reminders of this rule will be displayed if both or neither value is specified.</p>
<p>Here's an example of how to use the script as a defined process:</p>
<p>1. On a source Domain Controller, run "Import-and-Export_GPO_Links.ps1 -OutputFile C:\temp\migration.txt"</p>
<p>2. Move "migration.txt" to a destination Domain Controller and put it into the "C:\temp" folder.</p>
<p>3. On the destination Domain Controller, run "Import-and-Export_GPO_Links.ps1 -InputFile C:\temp\migration.txt"</p>
<p>4. Review the log file for any errors.</p>
<p><strong><span style="line-height: 115%; font-family: 'Calibri','sans-serif'; font-size: 11pt; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN; mso-fareast-language: EN-US; mso-bidi-language: AR-SA;" lang="EN">Disclaimer: The information on this site is provided "AS IS" with no warranties, confers no rights, and is not supported by the authors or Microsoft Corporation. Use of included script samples are subject to the terms specified in the </span></strong><span style="line-height: 115%; font-family: 'Calibri','sans-serif'; font-size: 11pt; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN; mso-fareast-language: EN-US; mso-bidi-language: AR-SA;" lang="EN"><a href="https://www.microsoft.com/info/cpyright.mspx">Terms of Use</a><strong><span style="font-family: 'Calibri','sans-serif'; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi;">.</span></strong></span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/telligent.evolution.components.attachments/01/8250/00/00/03/57/35/01/Import-and-Export_GPO_Links_Final.zip" original-url="https://blogs.technet.com/cfs-filesystemfile.ashx/__key/telligent-evolution-components-attachments/01-8250-00-00-03-57-35-01/Import_2D00_and_2D00_Export_5F00_GPO_5F00_Links_5F00_Final.zip">Import-and-Export_GPO_Links_Final.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Bulk Import of Group Policy Objects between Different Domains with PowerShell</title>
      <link>https://docs.microsoft.com/archive/blogs/manny/bulk-import-of-group-policy-objects-between-different-domains-with-powershell</link>
      <pubDate>Sun, 12 Feb 2012 08:25:00 GMT</pubDate>
      <dc:creator><![CDATA[Manny Murguia]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/manny/2012/02/12/bulk-import-of-group-policy-objects-between-different-domains-with-powershell/</guid>
      <description><![CDATA[I&rsquo;ve often worked with administrators who needed to duplicate an existing environment&rsquo;s...]]></description>
      <content:encoded><![CDATA[<p>I&rsquo;ve often worked with administrators who needed to duplicate an existing environment&rsquo;s set of Group Policy Objects (GPO&rsquo;s) to either a lab or other production domain. The challenge with that task is the source domain GPO&rsquo;s typically have domain-specific values included in them such as users and groups identified in the User Rights Assignment section of multiple GPO&rsquo;s and WMI filters linked to various GPO&rsquo;s. Typically, none of those values exist in the destination domain, so administrators are forced to either modify every GPO, as a post-import process, or re-create respective users, groups, and WMI filters in the destination domain and manually update a Migration Table. An example of how to use a Migration Table can be found at <a href="https://technet.microsoft.com/en-us/library/cc781458(WS.10).aspx">https://technet.microsoft.com/en-us/library/cc781458(WS.10).aspx</a>. This blog is going to provides examples of how to use PowerShell to automate the Migration Table mapping process and perform a bulk import of GPO&rsquo;s along with their WMI filters.</p>
<p><br />As with any other import process of GPO&rsquo;s and WMI filters into a new or existing Active Directory domain, we must first begin with an export from the source domain. PowerShell scripts to perform bulk exporting and importing WMI filters are available in an earlier blog of mine called Exporting and Importing WMI Filters with PowerShell. Exporting GPO&rsquo;s is already automated within the Group Policy Management Console (GPMC), so I won&rsquo;t cover those steps. If you need a review of exporting GPO&rsquo;s with GPMC, you can find it on TechNet at <a href="https://technet.microsoft.com/en-us/library/cc781458(WS.10).aspx">https://technet.microsoft.com/en-us/library/cc781458(WS.10).aspx</a>). When performing a backup of all GPO&rsquo;s from the source domain, ensure the destination is set to an empty folder, so there is only one version of each GPO from the source domain in the backup folder. The last piece of the puzzle needed before the scripts come into play is a Migration Table file. The Migration Table file editor is described <a href="https://technet.microsoft.com/en-us/library/cc779961(WS.10).aspx">https://technet.microsoft.com/en-us/library/cc779961(WS.10).aspx</a>. The option we&rsquo;ll need as output can be created using the &ldquo;Tools | Populate from Backup&rdquo; feature from the menu bar of the Migration Table editor (mtedit.exe). Once a copy of the source GPO&rsquo;s, a Migration Table XML file, and the WMI filters is available, they need to be moved over to the destination domain.<br />In the destination domain, it&rsquo;s time for PowerShell to get to work. The PowerShell scripts described below can be found as attachments to this blog. Each script will perform a single step of the import process. The three steps from a high level are as follows:</p>
<ol>
<li>Create objects in the destination domain and update the Migration Table XML file.</li>
<li>Import the GPO&rsquo;s into the destination domain</li>
<li>Link WMI filters to the new GPO&rsquo;s previously joined to the source domain GPO&rsquo;s</li>
</ol>
<p><br />Step 1 is handled by the script called &ldquo;CreateObjectsFromMigrationTable.ps1.&rdquo; This script does exactly what its name indicates and more. When running the script, there is only one required parameter: $MigrationTable. That parameter specifies the location of the Migration Table that will be used during the GPO import. Right about now, I can hear some of you asking, &ldquo;Do I still have to update that Migration Table file? It&rsquo;s such a pain!&rdquo; The answer is, &ldquo;No!&rdquo; When the &ldquo;CreateObjectsFromMigrationTable.ps1&rdquo; is run, it automatically updates the destination elements in the Migration Table file while creating domain objects identified from the source domain in the target domain. For example, if a group named &ldquo;%source_domain%\Auditors&rdquo; was used for the User Rights Assignment called &ldquo;Manage auditing and security log,&rdquo; the script would create an identically-named group in the destination domain called &ldquo;%destination_domain%\Auditors&rdquo; and update the Migration Table XML file with the new value. The scripts can handle users, groups of any type (e.g. Universal, Global, Domain Local), and computer objects. Finally, the script creates a log file that can be reviewed for objects created and other values the script does not currently handle (e.g. UNC paths used in the source GPO&rsquo;s). The updated Migration Table file can now be used by a GPO import.</p>
<p>Step 2 is handled by a second script called &ldquo;ImportAllGPOsFromBackup.ps1.&rdquo; This script requires two parameters: $MigrationTable and $BackupLocation. The $MigrationTable parameter should be set to the new Migration Table XML file created by the first script. The $BackupLocation parameter should be set to the folder location containing the GPO backups. When this script runs, it uses the $MIgrationTable file to import all the GPO&rsquo;s from the $BackupLocation. It does have limited error checking, so if a GPO already exists&nbsp; in the destination domain with the same name as a GPO being imported, the imported GPO name is prepended with the string &ldquo;DuplicateGPOOnImport &ndash;&ldquo; making the duplicate-named GPO&rsquo;s easy to identify after the import is complete. This script&nbsp; also creates a log file of its activity.</p>
<p>Step 3, the final script, is called &ldquo;Set-WMIFilterLinks.ps1&rdquo; and automatically links any WMI filter that was previously linked to the GPO in the source domain to the new GPO in the destination domain. For example if a GPO from the source domain had a WMI filter linked to it called &ldquo;Windows Server 2008&rdquo; the new GPO in the destination domain will have the same WMI filter linked to it. In order for this script to work, WMI filters with the same name as the source domain filters must exist in the destination domain. You can achieve that configuration using the scripts from my earlier blog: called Exporting and Importing WMI Filters with PowerShell. This script&nbsp; also creates a log file of its activity.</p>
<p>That does it for the bulk import of GPO&rsquo;s from one domain to another. The scripts could also be used to perform a recovery of GPO&rsquo;s and WMI filters, but that situation is probably not as commonly needed. Also, please note that none of the actually GPO links to Sites, Domain, or Organizational Units (OU&rsquo;s) will be persevered. A tool that does that would require quite of bit of code unless the Sites and OU structures were already in sync or made to be in sync between the source and destination domains.</p>
<p><strong><span style="line-height: 115%; font-family: 'Calibri','sans-serif'; font-size: 11pt; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN; mso-fareast-language: EN-US; mso-bidi-language: AR-SA;" lang="EN">Disclaimer: The information on this site is provided "AS IS" with no warranties, confers no rights, and is not supported by the authors or Microsoft Corporation. Use of included script samples are subject to the terms specified in the </span></strong><span style="line-height: 115%; font-family: 'Calibri','sans-serif'; font-size: 11pt; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN; mso-fareast-language: EN-US; mso-bidi-language: AR-SA;" lang="EN"><a href="https://www.microsoft.com/info/cpyright.mspx">Terms of Use</a><strong><span style="font-family: 'Calibri','sans-serif'; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi;">.</span></strong></span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/telligent.evolution.components.attachments/01/8250/00/00/03/48/04/08/Bulk_Import_of_GPOs_Between_Domains_PowerShell_Scripts.zip" original-url="https://blogs.technet.com/cfs-filesystemfile.ashx/__key/telligent-evolution-components-attachments/01-8250-00-00-03-48-04-08/Bulk_5F00_Import_5F00_of_5F00_GPOs_5F00_Between_5F00_Domains_5F00_PowerShell_5F00_Scripts.zip">Bulk_Import_of_GPOs_Between_Domains_PowerShell_Scripts.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Exporting and Importing WMI Filters with PowerShell: Part 2, Import</title>
      <link>https://docs.microsoft.com/archive/blogs/manny/exporting-and-importing-wmi-filters-with-powershell-part-2-import</link>
      <pubDate>Sun, 05 Feb 2012 07:31:00 GMT</pubDate>
      <dc:creator><![CDATA[Manny Murguia]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/manny/2012/02/05/exporting-and-importing-wmi-filters-with-powershell-part-2-import/</guid>
      <description><![CDATA[Now that we're through Exporting and Importing WMI Filters with PowerShell: Part 1, Export, the...]]></description>
      <content:encoded><![CDATA[<p>Now that we're through <a href="https://blogs.technet.com/b/manny/archive/2012/02/04/perform-a-full-export-and-import-of-wmi-filters-with-powershell.aspx">Exporting and Importing WMI Filters with PowerShell: Part 1, Export</a>, the import process can begin. Let's do a quick review of what will be imported. Since WMI filters are domain-specific, we only required three attributes for each WMI filter from the source domain: Name, Description, and Query. Our backup file ($BackupFile from Part 1 of this blog) contains a tab-delimited list of WMI filters. Here's a same of that file:</p>
<table border="1">
<tbody>
<tr>
<td>Name</td>
<td>Description</td>
<td>Query</td>
</tr>
<tr>
<td>Manufacturer Dell</td>
<td>Find all computer manufactured by Dell</td>
<td>1;3;10;62;WQL;root\CIMv2;Select * from WIN32_ComputerSystem where Manufacturer = "DELL";</td>
</tr>
<tr>
<td>Installed Memory &gt; 1Gb</td>
<td>Finds all computer with more than 1 Gb of RAM</td>
<td>1;3;10;74;WQL;root\CIMv2;Select * from WIN32_ComputerSystem where TotalPhysicalMemory &gt;= 1073741824;</td>
</tr>
</tbody>
</table>
<p>The backup file can be imported into Excel for easy modification of any particular field or the removal of filters by deleting the corresponding row in the backup file. The following script uses the backup file to create new WMI filters in the destination domain (the script is also attached as Import_All_WMI_Filters.ps1):</p>
<table border="1">
<tbody>
<tr>
<td>
<p><span style="font-family: courier new,courier;">param([String]$BackupFile)</span></p>
<p><span style="font-family: courier new,courier;">if ([String]::IsNullOrEmpty($BackupFile))</span><br /><span style="font-family: courier new,courier;">{</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; write-host -ForeGroundColor Red "BackupFile is a required parameter. Exiting Script.`n"</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; return</span><br /><span style="font-family: courier new,courier;">}</span></p>
<p><span style="font-family: courier new,courier;">import-module ActiveDirectory</span></p>
<p><span style="font-family: courier new,courier;">$Header = "Name","Description","Filter"</span><br /><span style="font-family: courier new,courier;">$WMIFilters = import-csv $BackupFile -Delimiter "`t" -Header $Header</span></p>
<p><span style="font-family: courier new,courier;">#The code below this line was modified to work with the file import code above this line. The original code can be found <a href="https://gallery.technet.microsoft.com/scriptcenter/f1491111-9f5d-4c83-b436-537eca9e8d94">here</a>.</span></p>
<p><span style="font-family: courier new,courier;">$defaultNamingContext = (get-adrootdse).defaultnamingcontext</span><br /><span style="font-family: courier new,courier;">$configurationNamingContext = (get-adrootdse).configurationNamingContext</span><br /><span style="font-family: courier new,courier;">$msWMIAuthor = "Administrator@" + [System.DirectoryServices.ActiveDirectory.Domain]::getcurrentdomain().name</span></p>
<p><span style="font-family: courier new,courier;">foreach ($WMIFilter in $WMIFilters)</span><br /><span style="font-family: courier new,courier;">{</span><br /><span style="font-family: courier new,courier;">$WMIGUID = [string]"{"+([System.Guid]::NewGuid())+"}"</span><br /><span style="font-family: courier new,courier;">$WMIDN = "CN="+$WMIGUID+",CN=SOM,CN=WMIPolicy,CN=System,"+$defaultNamingContext</span><br /><span style="font-family: courier new,courier;">$WMICN = $WMIGUID</span><br /><span style="font-family: courier new,courier;">$WMIdistinguishedname = $WMIDN</span><br /><span style="font-family: courier new,courier;">$WMIID = $WMIGUID</span><br />&nbsp;<br /><span style="font-family: courier new,courier;">$now = (Get-Date).ToUniversalTime()</span><br /><span style="font-family: courier new,courier;">$msWMICreationDate = ($now.Year).ToString("0000") + ($now.Month).ToString("00") + ($now.Day).ToString("00") + ($now.Hour).ToString("00") + ($now.Minute).ToString("00") + ($now.Second).ToString("00") + "." + ($now.Millisecond * 1000).ToString("000000") + "-000" </span><br /><span style="font-family: courier new,courier;">$msWMIName = $WMIFilter.Name</span><br /><span style="font-family: courier new,courier;">$msWMIParm1 = $WMIFilter.Description + " "</span><br /><span style="font-family: courier new,courier;">$msWMIParm2 = $WMIFilter.Filter</span></p>
<p><span style="font-family: courier new,courier;">$Attr = @{"msWMI-Name" = $msWMIName;"msWMI-Parm1" = $msWMIParm1;"msWMI-Parm2" = $msWMIParm2;"msWMI-Author" = $msWMIAuthor;"msWMI-ID"=$WMIID;"instanceType" = 4;"showInAdvancedViewOnly" = "TRUE";"distinguishedname" = $WMIdistinguishedname;"msWMI-ChangeDate" = $msWMICreationDate; "msWMI-CreationDate" = $msWMICreationDate} </span><br /><span style="font-family: courier new,courier;">$WMIPath = ("CN=SOM,CN=WMIPolicy,CN=System,"+$defaultNamingContext) </span><br />&nbsp;<br /><span style="font-family: courier new,courier;">New-ADObject -name $WMICN -type "msWMI-Som" -Path $WMIPath -OtherAttributes $Attr</span><br /><span style="font-family: courier new,courier;">}</span></p>
</td>
</tr>
</tbody>
</table>
<p>Let's take a closer look at what is going on in this script.</p>
<p>It starts by requiring the administrator&nbsp;to provide&nbsp;the&nbsp;$BackupFile parameter. If the parameter is not provided, the script exits and notifies the administrator.</p>
<table border="1">
<tbody>
<tr>
<td>
<p><span style="font-family: courier new,courier;">param([String]$BackupFile)</span></p>
<p><span style="font-family: courier new,courier;">if ([String]::IsNullOrEmpty($BackupFile))</span><br /><span style="font-family: courier new,courier;">{</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; write-host -ForeGroundColor Red "BackupFile is a required parameter. Exiting Script.`n"</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; return</span><br /><span style="font-family: courier new,courier;">}</span></p>
</td>
</tr>
</tbody>
</table>
<p>Next, we import the Active Directory Modules for PowerShell and&nbsp;populate the $WMIFilters variable with&nbsp;a full collection of WMI filters from the source domain along with the Name, Description, and Query for each filter described earlier. The headers are also inserted to allow for easy identification later in the script.</p>
<table style="width: 500px; height: 69px;" border="1">
<tbody>
<tr>
<td>
<p><span style="font-family: courier new,courier;">import-module ActiveDirectory</span></p>
<p><span style="font-family: courier new,courier;">$Header = "Name","Description","Filter"</span><br /><span style="font-family: courier new,courier;">$WMIFilters = import-csv $BackupFile -Delimiter "`t" -Header $Header</span></p>
</td>
</tr>
</tbody>
</table>
<p>Now we enter a for loop processing each row in the $BackupFile. In order to create the new WMI filter object (msWMI-Som objectClass), we'll need a new Globally Unique Identifier (GUID) stored in $WMIGUID. Using the GUID, we store the Distinguished Name (DN) in the $WMIDN variable. We'll also need the Container Name ($WMICN). The Container for WMI filters in Active Directory is represented by the GUID. The DN of the new WMI filter is then stored for later use&nbsp;in $WMIdistinguishedname. Finally, the GUID is stored for later use in $WMIID.</p>
<table border="1">
<tbody>
<tr>
<td><span style="font-family: courier new,courier;">foreach ($WMIFilter in $WMIFilters)</span><br /><span style="font-family: courier new,courier;">{</span><br /><span style="font-family: courier new,courier;">$WMIGUID = [string]"{"+([System.Guid]::NewGuid())+"}"</span><br /><span style="font-family: courier new,courier;">$WMIDN = "CN="+$WMIGUID+",CN=SOM,CN=WMIPolicy,CN=System,"+$defaultNamingContext</span><br /><span style="font-family: courier new,courier;">$WMICN = $WMIGUID</span><br /><span style="font-family: courier new,courier;">$WMIdistinguishedname = $WMIDN</span><br /><span style="font-family: courier new,courier;">$WMIID = $WMIGUID</span></td>
</tr>
</tbody>
</table>
<p>The next section prepares more variables for use later in the script. $now stores the current date/time (UTC). $msWMICreationDate stores the date/time in a converted format for storage in the msWMI-CreationDate attribute of the WMI filter. Finally, the Name, Description, and Query of the WMI filter are stored in $msWMIName, $msWMIParm1, and $msWMIParm2 variables, respectively.</p>
<table border="1">
<tbody>
<tr>
<td><span style="font-family: courier new,courier;">$now = (Get-Date).ToUniversalTime()</span><br /><span style="font-family: courier new,courier;">$msWMICreationDate = ($now.Year).ToString("0000") + ($now.Month).ToString("00") + ($now.Day).ToString("00") + ($now.Hour).ToString("00") + ($now.Minute).ToString("00") + ($now.Second).ToString("00") + "." + ($now.Millisecond * 1000).ToString("000000") + "-000" </span><br /><span style="font-family: courier new,courier;">$msWMIName = $WMIFilter.Name</span><br /><span style="font-family: courier new,courier;">$msWMIParm1 = $WMIFilter.Description + " "</span><br /><span style="font-family: courier new,courier;">$msWMIParm2 = $WMIFilter.Filter</span></td>
</tr>
</tbody>
</table>
<p>The last two variables we'll need to create the WMI filter are $Attr and $WMIPath. $Attr represents all the attributes required for creating a WMI filter object in Active Directory. $WMIPath identifies the DN of the location where WMI filters are stored in Active Directory.</p>
<table border="1">
<tbody>
<tr>
<td><span style="font-family: courier new,courier;">$Attr = @{"msWMI-Name" = $msWMIName;"msWMI-Parm1" = $msWMIParm1;"msWMI-Parm2" = $msWMIParm2;"msWMI-Author" = $msWMIAuthor;"msWMI-ID"=$WMIID;"instanceType" = 4;"showInAdvancedViewOnly" = "TRUE";"distinguishedname" = $WMIdistinguishedname;"msWMI-ChangeDate" = $msWMICreationDate; "msWMI-CreationDate" = $msWMICreationDate} </span><br /><span style="font-family: courier new,courier;">$WMIPath = ("CN=SOM,CN=WMIPolicy,CN=System,"+$defaultNamingContext) </span></td>
</tr>
</tbody>
</table>
<p>The final line in the script is what creates the new WMI filter object. The parameters passed to the "New-ADObject" command are as follows:</p>
<ul>
<li>-name: The Container Name of the WMI filter in Active Directory (not the friendly name)</li>
<li>-type: The objectClass for WMI filters (msWMI-Som)</li>
<li>-Path:&nbsp;The DN of the location where WMI filters are stored in Active Directory</li>
<li>-OtherAttributes:&nbsp;The attributes required to create the new WMI filter object</li>
</ul>
<table border="1">
<tbody>
<tr>
<td><span style="font-family: courier new,courier;">New-ADObject -name $WMICN -type "msWMI-Som" -Path $WMIPath -OtherAttributes $Attr</span><br /><span style="font-family: courier new,courier;">}</span></td>
</tr>
</tbody>
</table>
<p>That does it for the import script. There is one special note to be made during the import process: There is no error checking. Also, if you have existing WMI filters in your domain with names that conflict with the names of the WMI filter you are importing using this script, new WMI filters with the same friendly name will be created (your existing ones will not be updated or impacted in any way). Still, I recommend working out those conflicts before running the import script or the conflicting names can eventually lead to confusion when administering WMI filter links and filters.</p>
<p>My next series of scripts will provide administrators with a way, using PowerShell, to perform bulk imports of Group Policy Object and perform automated linking of previously-linked WMI filters to those GPO's. Sounds exciting, right?</p>
<p><strong>Disclaimer: The information on this site is provided "AS IS" with no warranties, confers no rights, and is not supported by the authors or Microsoft Corporation. Use of included script samples are subject to the terms specified in the </strong><a href="https://www.microsoft.com/info/cpyright.mspx">Terms of Use</a><strong>.</strong></p>
<p>&nbsp;</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/telligent.evolution.components.attachments/01/8250/00/00/03/47/89/62/Import_All_WMI_Filters.ps1" original-url="https://blogs.technet.com/cfs-filesystemfile.ashx/__key/telligent-evolution-components-attachments/01-8250-00-00-03-47-89-62/Import_5F00_All_5F00_WMI_5F00_Filters.ps1">Import_All_WMI_Filters.ps1</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Exporting and Importing WMI Filters with PowerShell: Part 1, Export</title>
      <link>https://docs.microsoft.com/archive/blogs/manny/exporting-and-importing-wmi-filters-with-powershell-part-1-export</link>
      <pubDate>Sat, 04 Feb 2012 17:47:00 GMT</pubDate>
      <dc:creator><![CDATA[Manny Murguia]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/manny/2012/02/04/exporting-and-importing-wmi-filters-with-powershell-part-1-export/</guid>
      <description><![CDATA[Since this is my first blog post, I'd like to take quick second to introduce myself. My name is...]]></description>
      <content:encoded><![CDATA[<p>Since this is my first blog post, I'd like to take quick second to introduce myself. My name is Manny Murguia, and I'm a Senior Consultant at Microsoft. It's been a little over 4 years since I started, and it's been a wild ride so far. I'm looking forward to blogging and hope you get out much out of it as I put in to it! You can find more about me at the About link on my <a href="https://blogs.technet.com/manny">homepage</a>. With introductions out of the way, here we go!</p>
<p>Since I'll be writing about WMI filters, it's only appropriate for me to give a shout out to Mike Stephens. Mike, without knowing it,&nbsp;helped push me to write this blog based on a post of his back in 2008 on the Directory Services&nbsp;Team Blog:&nbsp;<a href="https://blogs.technet.com/b/askds/archive/2008/05/16/bulk-exporting-and-importing-wmi-filters-for-group-policy.aspx">bulk-exporting-and-importing-wmi-filters-for-group-policy</a>. I decided to put PowerShell to the test and come up with another method of exporting and importing WMI filters in Active Directory. Before you keep reading this post, take a second to visit <a href="https://gallery.technet.microsoft.com/scriptcenter/f1491111-9f5d-4c83-b436-537eca9e8d94">this site</a> if you're just looking for a way to create a ton of boxed WMI filters for your environment. My post is directed at those administrators&nbsp;who want to duplicate an existing environment. I will, however, admit that a large piece of the import script you see in "Exporting and Importing WMI Filters with PowerShell: Part 2, Import" came directly from that site (that does it for my anti-plagiarism plug).</p>
<p>Anyone who has worked with Group Policy has undoubtedly used Group Policy Management Console (GPMC). With GPMC, creating, linking, and deleting Group Policy Objects (GPO's) and WMI filters is a snap. The biggest challenge with GPMC, as Mike mentioned back in 2008, is still how to export and import WMI filters. The painstaking process of individually exporting and importing the filters can take&nbsp;good chunk out of your workday. In my experience, this process itself ends up being repeated multiple times since there is always someone asking for a "dump" of production GPO's and WMI filters for their lab (or even for some other production system they happen to be building without you - nothing personal).</p>
<p>Welcome, PowerShell. Since the introduction of Active Directory modules for PowerShell, administrators have had a new tool in their arsenal. Rejoice, and take advantage of it! When it comes to&nbsp;managing Active Directory objects,&nbsp;PowerShell is&nbsp;quite "PowerFull." WMI filters, of course, fall into that category. Since WMI filters are all from an objectClass called "msWMI-Som," we can collect all WMI filters in a domain using the following command:</p>
<p><span style="font-family: courier new,courier;">$WMIFilters = Get-ADObject -Filter 'objectClass -eq "msWMI-Som"' -Properties "msWMI-Name","msWMI-Parm1","msWMI-Parm2"</span></p>
<p>What doe all that mean? Here's a quick breakdown:</p>
<p><span style="font-family: courier new,courier;">$WMIFilters</span>: This value is just an object we are creating to store our WMI Filters</p>
<p><span style="font-family: courier new,courier;">Get-ADObject</span>: This cmdlet allows us to populate our object with a collection object AD objects matching the -Filter parameter</p>
<p><span style="font-family: courier new,courier;">-Filter</span>: This parameter allows us to filter on what objects will be returned from the query. Since we know WMI filters are of objectClass "msWMI-Som" the filter is pretty straightforward.</p>
<p><span style="font-family: courier new,courier;">-Properties</span>: This parameters allows us to specify which AD attributes should be collected for the objects returned by the query. With WMI filters, we really only care about three attributes for WMI filters:</p>
<ul>
<li><span style="font-family: courier new,courier;">msWMI-Name</span>: The friendly name of the WMI filter</li>
<li><span style="font-family: courier new,courier;">msWMI-Parm1</span>: The description of the WMI filter</li>
<li><span style="font-family: courier new,courier;">msWMI-Parm2</span>: The query and other related data of the WMI filter</li>
</ul>
<p>The following script is also attached to this post as Backup_All_WMI_Filters.ps1.</p>
<table border="1">
<tbody>
<tr>
<td>
<p><span style="font-family: courier new,courier;"> param([String]$BackupFile)</span></p>
<p><span style="font-family: courier new,courier;"> if ([String]::IsNullOrEmpty($BackupFile))</span><br /><span style="font-family: courier new,courier;"> { </span><br /><span style="font-family: courier new,courier;">&nbsp; $BackupFile = "C:\WMI_Full_Backup.csv"</span><br /><span style="font-family: courier new,courier;">&nbsp; set-content $BackupFile $NULL</span><br /><span style="font-family: courier new,courier;"> }</span><br /><span style="font-family: courier new,courier;"> else</span><br /><span style="font-family: courier new,courier;"> {</span><br /><span style="font-family: courier new,courier;">&nbsp; set-content $BackupFile $NULL</span><br /><span style="font-family: courier new,courier;"> }</span></p>
<p><span style="font-family: courier new,courier;"> import-module ActiveDirectory</span></p>
<p><span style="font-family: courier new,courier;"> $WMIFilters = Get-ADObject -Filter 'objectClass -eq "msWMI-Som"' -Properties "msWMI-Name","msWMI-Parm1","msWMI-Parm2"</span></p>
<p><span style="font-family: courier new,courier;"> foreach ($WMIFilter in $WMIFilters)</span><br /><span style="font-family: courier new,courier;"> {</span><br /><span style="font-family: courier new,courier;">&nbsp; $NewContent = $WMIFilter."msWMI-Name" + "`t" + $WMIFilter."msWMI-Parm1" + "`t" + $WMIFilter."msWMI-Parm2"</span><br /><span style="font-family: courier new,courier;">&nbsp; add-content $NewContent -path $BackupFile</span><br /><span style="font-family: courier new,courier;"> }</span></p>
<p><span style="font-family: courier new,courier;"> clear</span></p>
<p><span style="font-family: courier new,courier;"> write-host "A full backup of WMI Filters has been stored at $BackupFile`n"</span></p>
</td>
</tr>
</tbody>
</table>
<p>So what does this script do? Let's check it out.</p>
<p>It starts by allow the person running the script to provide just one parameter called $BackupLocation. If that parameter is not specified, it defaults to C:\WMI_Full_Backup.csv. Either way, the file content is set to $NULL.</p>
<table border="1">
<tbody>
<tr>
<td>
<p><span style="font-family: courier new,courier;">param([String]$BackupFile)</span></p>
<p><span style="font-family: courier new,courier;"> if ([String]::IsNullOrEmpty($BackupFile))</span><br /><span style="font-family: courier new,courier;"> {</span><br /><span style="font-family: courier new,courier;">&nbsp; $BackupFile = "C:\WMI_Full_Backup.csv"</span><br /><span style="font-family: courier new,courier;">&nbsp; set-content $BackupFile $NULL</span><br /><span style="font-family: courier new,courier;"> }</span><br /><span style="font-family: courier new,courier;"> else</span><br /><span style="font-family: courier new,courier;"> {</span><br /><span style="font-family: courier new,courier;">&nbsp; set-content $BackupFile $NULL</span><br /><span style="font-family: courier new,courier;"> }</span></p>
</td>
</tr>
</tbody>
</table>
<p>Next, we import the Active Directory Modules for PowerShell and&nbsp;"dump" a full collection of WMI filters from the domain along with the Name, Description, and Query for each filter described earlier.</p>
<table border="1">
<tbody>
<tr>
<td>import-module ActiveDirectory
<p><span style="font-family: courier new,courier;"> $WMIFilters = Get-ADObject -Filter 'objectClass -eq "msWMI-Som"' -Properties "msWMI-Name","msWMI-Parm1","msWMI-Parm2"</span></p>
</td>
</tr>
</tbody>
</table>
<p>Now comes the actually export process. We'll run through a loop for each WMI filter in our $WMIFilters collection and do two things: Structure a tab-delimited string that will be added to our $BackupFile and append that string to our $BackupFile.</p>
<table border="1">
<tbody>
<tr>
<td>
<p><span style="font-family: courier new,courier;"><span style="font-family: courier new,courier;"> foreach ($WMIFilter in $WMIFilters)</span><br /><span style="font-family: courier new,courier;"> {</span><br /><span style="font-family: courier new,courier;">&nbsp; $NewContent = $WMIFilter."msWMI-Name" + "`t" + $WMIFilter."msWMI-Parm1" + "`t" + $WMIFilter."msWMI-Parm2"</span><br /><span style="font-family: courier new,courier;">&nbsp; add-content $NewContent -path $BackupFile</span><br /><span style="font-family: courier new,courier;"> }</span></span></p>
</td>
</tr>
</tbody>
</table>
<p>The last two commands in the script just present a clean output the console to notify the administrator the script is complete. Notice there was not a ton of error-checking in this script. Who has time for that?</p>
<table border="1">
<tbody>
<tr>
<td>
<p><span style="font-family: courier new,courier;"> clear</span></p>
<p><span style="font-family: courier new,courier;"> write-host "A full backup of WMI Filters has been stored at $BackupFile`n"</span></p>
</td>
</tr>
</tbody>
</table>
<p>By now, you have noticed we don't have actual WMI filters at all. In fact, we only have exactly what we need. The Name, Description, and Query will work fine for the import process.&nbsp;The backup file can be imported using the script provided in&nbsp;<a href="https://blogs.technet.com/b/manny/archive/2012/02/05/exporting-and-importing-wmi-filters-with-powershell-part-2-import.aspx">Exporting and Importing WMI Filters with PowerShell: Part 2, Import</a>.</p>
<p><strong>Disclaimer: The information on this site is provided "AS IS" with no warranties, confers no rights, and is not supported by the authors or Microsoft Corporation. Use of included script samples are subject to the terms specified in the </strong><a href="https://www.microsoft.com/info/cpyright.mspx">Terms of Use</a><strong>.</strong></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/telligent.evolution.components.attachments/01/8250/00/00/03/47/89/35/Backup_All_WMI_Filters.ps1" original-url="https://blogs.technet.com/cfs-filesystemfile.ashx/__key/telligent-evolution-components-attachments/01-8250-00-00-03-47-89-35/Backup_5F00_All_5F00_WMI_5F00_Filters.ps1">Backup_All_WMI_Filters.ps1</a></p>]]></content:encoded>
    </item>
  </channel>
</rss>