[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"sanity-8z5CiywTzb7eduIUw-uhzCgZenKAPo-F9P1CAXLrghI":3,"sanity-lZDbhsK-aAllLBZIfQZugooChqmcNZj7yB6lOHSAg90":546},{"data":4,"sourceMap":-1},{"latestPodcast":5,"latestReleases":14,"post":39,"recent":521},[6],{"_id":7,"publishedAt":8,"slug":9,"sponsored":12,"title":13},"f83eb5f0-1237-487f-84d8-f7abf2318c39","2026-06-25T07:40:00.000Z",{"_type":10,"current":11},"slug","code-isnt-causing-your-production-failures",null,"Code isn’t the only thing causing your production failures",[15,21,27,33],{"_id":16,"publishedAt":17,"slug":18,"title":20},"eb5b66eb-9410-4329-83bb-22bbff39402a","2026-04-28T13:00:00.000Z",{"_type":10,"current":19},"turn-scattered-knowledge-into-trusted-intelligence","Turning scattered knowledge into trusted intelligence: Stack Internal 2026.3",{"_id":22,"publishedAt":23,"slug":24,"title":26},"369c2401-b62e-4a37-8ff8-bf603023ecad","2026-03-02T15:03:00.988Z",{"_type":10,"current":25},"what-s-new-at-stack-overflow-march-2026","What’s new at Stack Overflow: March 2026",{"_id":28,"publishedAt":29,"slug":30,"title":32},"5e9053a4-07ea-447c-91ea-29e0b6228537","2026-02-02T15:00:00.000Z",{"_type":10,"current":31},"what-s-new-at-stack-overflow-february-2026","What’s new at Stack Overflow: February 2026",{"_id":34,"publishedAt":35,"slug":36,"title":38},"a1b538eb-a8a6-46d0-80a1-ac70ec9bb935","2026-01-05T10:00:00.000-05:00",{"_type":10,"current":37},"what-s-new-at-stack-overflow-january-2026","What’s new at Stack Overflow: January 2026",{"_createdAt":40,"_id":41,"_rev":42,"_type":43,"_updatedAt":44,"author":45,"body":61,"comments":500,"dateUrl":501,"excerpt":172,"image":502,"legacyBody":505,"product":12,"publishedAt":508,"slug":509,"sponsored":12,"tags":511,"title":520,"visible":500},"2023-05-25T09:37:04Z","wp-post-4970","9HpbCsT2tq0xwozQfkfnl5","blogPost","2023-07-13T14:54:59Z",[46],{"_createdAt":47,"_id":48,"_rev":49,"_type":50,"_updatedAt":51,"avatar":52,"employee":57,"name":58,"slug":59},"2023-05-23T16:27:18Z","wp-author-150","dpQ2IysUm09sCEUZjPVCUI","blogAuthor","2023-12-14T17:23:52Z",{"_type":53,"asset":54},"image",{"_ref":55,"_type":56},"image-b34c0262b663e7158040f6ff27affed2a99aa511-1024x1024-png","reference","former","Dan O’Boyle",{"current":60},"selfcommit",[62,112,129,138,168,173,181,189,197,207,215,223,242,250,270,278,286,290,298,307,315,323,331,350,354,373,381,389,397,421,429,437,460,468,476,484,492],{"_key":63,"_type":64,"children":65,"markDefs":103,"style":111},"726be94a6f20","block",[66,71,76,80,85,89,94,98],{"_key":67,"_type":68,"marks":69,"text":70},"726be94a6f200","span",[],"Often automating a task is ",{"_key":72,"_type":68,"marks":73,"text":75},"726be94a6f201",[74],"ed630a7d6f98","not worth the time",{"_key":77,"_type":68,"marks":78,"text":79},"726be94a6f202",[]," and rarely takes ",{"_key":81,"_type":68,"marks":82,"text":84},"726be94a6f203",[83],"614836607fc1","the time planned",{"_key":86,"_type":68,"marks":87,"text":88},"726be94a6f204",[],". At StackExchange we have lots of people on our team and in our community ",{"_key":90,"_type":68,"marks":91,"text":93},"726be94a6f205",[92],"a01d0c4c0c23","who are amazing at Powershell",{"_key":95,"_type":68,"marks":96,"text":97},"726be94a6f206",[],". ",{"_key":99,"_type":68,"marks":100,"text":102},"726be94a6f207",[101],"strong","I am not one of those people.",[104,107,109],{"_key":74,"_type":105,"href":106,"reference":12},"link","http://xkcd.com/1205/",{"_key":83,"_type":105,"href":108,"reference":12},"http://xkcd.com/1319/",{"_key":92,"_type":105,"href":110,"reference":12},"http://stackoverflow.com/tags/powershell/hot","normal",{"_key":113,"_type":64,"children":114,"markDefs":128,"style":111},"b9af258c9233",[115,120,124],{"_key":116,"_type":68,"marks":117,"text":119},"b9af258c92330",[118],"em","Is it possible to save time using Powershell, even if you're not a guru?",{"_key":121,"_type":68,"marks":122,"text":123},"b9af258c92331",[]," ",{"_key":125,"_type":68,"marks":126,"text":127},"b9af258c92332",[101],"Sure!",[],{"_key":130,"_type":64,"children":131,"markDefs":136,"style":137},"2501b8da9bb3",[132],{"_key":133,"_type":68,"marks":134,"text":135},"2501b8da9bb30",[],"Framing the Problem",[],"h1",{"_key":139,"_type":64,"children":140,"markDefs":163,"style":111},"e290d483603a",[141,145,150,154,159],{"_key":142,"_type":68,"marks":143,"text":144},"e290d483603a0",[],"At Stack we use ",{"_key":146,"_type":68,"marks":147,"text":149},"e290d483603a1",[148],"a88453296ca8","Google Apps for Work",{"_key":151,"_type":68,"marks":152,"text":153},"e290d483603a2",[],". Google Apps for Work includes a great tool for linking your existing Active Directory structure to your Google Accounts. That tool, ",{"_key":155,"_type":68,"marks":156,"text":158},"e290d483603a3",[157],"b91b4a3c61fd","Google Apps Directory Sync",{"_key":160,"_type":68,"marks":161,"text":162},"e290d483603a4",[]," (GADS) allows a company to sync Active Directory Users and Groups with Google email accounts and mailing lists. We already sync our users with email addresses, but my task is to also link our security groups with email distribution lists.",[164,166],{"_key":148,"_type":105,"href":165,"reference":12},"http://www.google.com/enterprise/apps/business/",{"_key":157,"_type":105,"href":167,"reference":12},"https://support.google.com/a/answer/106368?hl=en",{"_key":169,"_type":53,"alt":12,"asset":170,"caption":172,"markDefs":12},"4ca1d6b291b0",{"_ref":171,"_type":56},"image-dbcba84bb5630bcda84af8be234e689f3f8c1509-794x518-png","",{"_key":174,"_type":64,"children":175,"markDefs":180,"style":111},"b320cd703b9f",[176],{"_key":177,"_type":68,"marks":178,"text":179},"b320cd703b9f0",[],"In a fresh environment, this would be incredibly easy. However, we have a number of mailing lists that exist on the \"Google side\" that don't have matching security groups in AD. This issue is compounded because when group sync is enabled in GADS, any group that does not match an AD group will be deleted on the Google side. As a friend put it:",[],{"_key":182,"_type":64,"children":183,"markDefs":188,"style":111},"16f904aa530e",[184],{"_key":185,"_type":68,"marks":186,"text":187},"16f904aa530e0",[101],"We need to attach a trailer to a moving vehicle.",[],{"_key":190,"_type":64,"children":191,"markDefs":196,"style":137},"626996e75bdc",[192],{"_key":193,"_type":68,"marks":194,"text":195},"626996e75bdc0",[],"Steps to resolve the problem:",[],{"_key":198,"_type":64,"children":199,"level":204,"listItem":205,"markDefs":206,"style":111},"f82197ab18fd",[200],{"_key":201,"_type":68,"marks":202,"text":203},"f82197ab18fd0",[],"Match existing AD Security Groups to Google mailing lists.",1,"number",[],{"_key":208,"_type":64,"children":209,"level":204,"listItem":205,"markDefs":214,"style":111},"11f04f3d22a0",[210],{"_key":211,"_type":68,"marks":212,"text":213},"11f04f3d22a00",[],"Generate AD Security Groups that don't exist for matching Google mailing lists.",[],{"_key":216,"_type":64,"children":217,"level":204,"listItem":205,"markDefs":222,"style":111},"84d94be78b82",[218],{"_key":219,"_type":68,"marks":220,"text":221},"84d94be78b820",[],"Populate the AD Security Groups with the correct users",[],{"_key":224,"_type":64,"children":225,"markDefs":239,"style":111},"8be4bf5ab9d7",[226,230,235],{"_key":227,"_type":68,"marks":228,"text":229},"8be4bf5ab9d70",[],"If you're familiar with GADS, you'll know #1 is pretty easy. Using an AD filter we can ",{"_key":231,"_type":68,"marks":232,"text":234},"8be4bf5ab9d71",[233],"d1e70c28ae65","match groups in our AD structure",{"_key":236,"_type":68,"marks":237,"text":238},"8be4bf5ab9d72",[]," to existing Google Groups. The only concern here is to make sure that the AD groups actually have the same users as the existing Google group, since no sync has occurred previously.",[240],{"_key":233,"_type":105,"href":241,"reference":12},"https://www.google.com/support/enterprise/static/gapps/docs/admin/en/gads/admin/config_group_sync.html",{"_key":243,"_type":64,"children":244,"markDefs":249,"style":111},"4ba1bce7c75a",[245],{"_key":246,"_type":68,"marks":247,"text":248},"4ba1bce7c75a0",[],"The second issue, Generating AD Security Groups that don't exist as mailing lists, poses a problem.",[],{"_key":251,"_type":64,"children":252,"markDefs":269,"style":111},"5cb954a3abc2",[253,257,261,265],{"_key":254,"_type":68,"marks":255,"text":256},"5cb954a3abc20",[],"Running a simulated Sync on GADS shows ",{"_key":258,"_type":68,"marks":259,"text":260},"5cb954a3abc21",[101],"80 Google Groups",{"_key":262,"_type":68,"marks":263,"text":264},"5cb954a3abc22",[]," without a matching AD security group. ",{"_key":266,"_type":68,"marks":267,"text":268},"5cb954a3abc23",[101],"(That's quite a few clicks...)",[],{"_key":271,"_type":64,"children":272,"markDefs":277,"style":111},"24706dd5e8cd",[273],{"_key":274,"_type":68,"marks":275,"text":276},"24706dd5e8cd0",[],"This is our first opportunity to use Powershell to solve our problems.",[],{"_key":279,"_type":64,"children":280,"markDefs":285,"style":111},"168268671ab3",[281],{"_key":282,"_type":68,"marks":283,"text":284},"168268671ab30",[],"I start by grabbing a list of groups that aren't in AD. GADS simulated Sync logs those groups in a way that is easily copy/pasted into a nice Tab separated format.",[],{"_key":287,"_type":53,"alt":12,"asset":288,"caption":172,"markDefs":12},"6dcabc7847af",{"_ref":289,"_type":56},"image-65f5f6b60c8831257b3677c2b2ed9148a9544ac4-454x219-gif",{"_key":291,"_type":64,"children":292,"markDefs":297,"style":111},"79e4e9a3088b",[293],{"_key":294,"_type":68,"marks":295,"text":296},"79e4e9a3088b0",[101],"Now that we have the groups we can get them into AD:",[],{"_key":299,"_type":64,"children":300,"level":204,"listItem":305,"markDefs":306,"style":111},"3da9f526a722",[301],{"_key":302,"_type":68,"marks":303,"text":304},"3da9f526a7220",[],"Read the CSV into powershell","bullet",[],{"_key":308,"_type":64,"children":309,"level":204,"listItem":305,"markDefs":314,"style":111},"b674c2e02de5",[310],{"_key":311,"_type":68,"marks":312,"text":313},"b674c2e02de50",[],"For each group, generate a security group with matching name.",[],{"_key":316,"_type":64,"children":317,"markDefs":322,"style":111},"02221dbea93e",[318],{"_key":319,"_type":68,"marks":320,"text":321},"02221dbea93e0",[118],"\"BUT I DONT KNOW HOW TO DO THAT IN POWERSHELL\"",[],{"_key":324,"_type":64,"children":325,"markDefs":330,"style":111},"878e60c84eb2",[326],{"_key":327,"_type":68,"marks":328,"text":329},"878e60c84eb20",[],"That's ok. Lets use our minimal knowledge, and Google to figure out how.",[],{"_key":332,"_type":64,"children":333,"markDefs":347,"style":111},"db2bb9d36e21",[334,338,343],{"_key":335,"_type":68,"marks":336,"text":337},"db2bb9d36e210",[],"A quick Google search shows a Technet article on ",{"_key":339,"_type":68,"marks":340,"text":342},"db2bb9d36e211",[341],"8d7d0332e190","Import-CSV",{"_key":344,"_type":68,"marks":345,"text":346},"db2bb9d36e212",[],". Reading Microsoft Technet articles is an art all its own. These articles provide lots of in depth information on Import-CSV. While more information is GREAT, we're trying to Get Things Done. Let's CTRL + F to find relevant examples:",[348],{"_key":341,"_type":105,"href":349,"reference":12},"http://technet.microsoft.com/en-us/library/ee176874.aspx",{"_key":351,"_type":53,"alt":12,"asset":352,"caption":172,"markDefs":12},"587bb45f122a",{"_ref":353,"_type":56},"image-8681cfd16b513fa1e6b5222046b95159a726f4a6-562x500-gif",{"_key":355,"_type":64,"children":356,"markDefs":370,"style":111},"45c7c5565e55",[357,361,366],{"_key":358,"_type":68,"marks":359,"text":360},"45c7c5565e550",[],"We quickly isolate the example CSV import. By dumping that import into a variable ($csv) we now have an object Powershell can manipulate. Following a similar search and CTRL + F for ",{"_key":362,"_type":68,"marks":363,"text":365},"45c7c5565e551",[364],"8b5d2e64d88d","New-ADGoup",{"_key":367,"_type":68,"marks":368,"text":369},"45c7c5565e552",[]," we end up a short script:",[371],{"_key":364,"_type":105,"href":372,"reference":12},"http://technet.microsoft.com/en-us/library/ee617258.aspx",{"_key":374,"_type":64,"children":375,"markDefs":380,"style":111},"26eebba48df9",[376],{"_key":377,"_type":68,"marks":378,"text":379},"26eebba48df90",[],"{% highlight powershell %} $csv = Import-Csv -Delimiter t -Encoding UTF8 -Header Groups -Path C:Usersdoboyle.STACKEXCHANGEDesktopgroups.txt",[],{"_key":382,"_type":64,"children":383,"markDefs":388,"style":111},"6a8191b946e8",[384],{"_key":385,"_type":68,"marks":386,"text":387},"6a8191b946e80",[],"foreach ($i in $csv) { $Group = $i.Groups New-ADGroup -Name $Group -GroupCategory Security -GroupScope Global -DisplayName $Group -Path \"OU=GADS_Groups,OU=IT,DC=Something,DC=YourDomain,DC=com\" -Description $Group } {% endhighlight %}",[],{"_key":390,"_type":64,"children":391,"markDefs":396,"style":111},"58b66a32c17a",[392],{"_key":393,"_type":68,"marks":394,"text":395},"58b66a32c17a0",[101],"So Close.. But wait there's more!",[],{"_key":398,"_type":64,"children":399,"markDefs":420,"style":111},"5a6c3bb4e721",[400,404,408,412,416],{"_key":401,"_type":68,"marks":402,"text":403},"5a6c3bb4e7210",[],"Problem 1 and 2 are resolved, but we still need to populate those AD groups. Many of the groups only have a few users, and are easily updated using the build in Active Directory Interface. Some groups are larger. So large that the existing AD interface would require ",{"_key":405,"_type":68,"marks":406,"text":407},"5a6c3bb4e7211",[101],"hundreds",{"_key":409,"_type":68,"marks":410,"text":411},"5a6c3bb4e7212",[],", or even ",{"_key":413,"_type":68,"marks":414,"text":415},"5a6c3bb4e7213",[101],"thousands of clicks",{"_key":417,"_type":68,"marks":418,"text":419},"5a6c3bb4e7214",[],". If you think that's too many clicks, you'd be right.",[],{"_key":422,"_type":64,"children":423,"markDefs":428,"style":137},"8a787496dea6",[424],{"_key":425,"_type":68,"marks":426,"text":427},"8a787496dea60",[],"Powershell can help!",[],{"_key":430,"_type":64,"children":431,"markDefs":436,"style":111},"9762edca21d9",[432],{"_key":433,"_type":68,"marks":434,"text":435},"9762edca21d90",[],"Just as before, GADS simulated sync will return a list of users effected by a planned sync. We can again pull that list of users into a TSV.",[],{"_key":438,"_type":64,"children":439,"markDefs":457,"style":111},"64cb80d68bf1",[440,444,448,453],{"_key":441,"_type":68,"marks":442,"text":443},"64cb80d68bf10",[101],"Lets modify our existing Powershell script to populate AD groups:",{"_key":445,"_type":68,"marks":446,"text":447},"64cb80d68bf11",[],"\nWe match on email address, not AD username, so we need to find the AD user with a matching email address, and add them to the correct group. ",{"_key":449,"_type":68,"marks":450,"text":452},"64cb80d68bf12",[451],"069061e0941f","Get-ADUser",{"_key":454,"_type":68,"marks":455,"text":456},"64cb80d68bf13",[]," has a filter option, which accepts a string. If we set the email address provided by GADS as the filtered string, we should always get the user we want.",[458],{"_key":451,"_type":105,"href":459,"reference":12},"http://technet.microsoft.com/en-us/library/ee617241.aspx",{"_key":461,"_type":64,"children":462,"markDefs":467,"style":111},"e4cb0cf7d41c",[463],{"_key":464,"_type":68,"marks":465,"text":466},"e4cb0cf7d41c0",[],"{% highlight powershell %} $Group = \"All\"",[],{"_key":469,"_type":64,"children":470,"markDefs":475,"style":111},"09af24747441",[471],{"_key":472,"_type":68,"marks":473,"text":474},"09af247474410",[],"$path = $(\"C:Usersdoboyle.STACKEXCHANGEDesktop\", $Group, \".txt\" -join \"\")",[],{"_key":477,"_type":64,"children":478,"markDefs":483,"style":137},"bb5885f6227b",[479],{"_key":480,"_type":68,"marks":481,"text":482},"bb5885f6227b0",[],"There's no Header in our TSV, so we define one as \"GoogleUser\"",[],{"_key":485,"_type":64,"children":486,"markDefs":491,"style":111},"c686a533678f",[487],{"_key":488,"_type":68,"marks":489,"text":490},"c686a533678f0",[],"$csv = Import-Csv -Delimiter t -Encoding UTF8 -Header GoogleUser -Path $path foreach ($user in $csv) { $email = $($user.GoogleUser.ToString(), \"@stackoverflow.com\" -join \"\") $user = Get-ADUser -Filter {mail -like $email} Add-ADGroupMember $Group $user } {% endhighlight %}",[],{"_key":493,"_type":64,"children":494,"markDefs":499,"style":111},"5ea4c4dd5163",[495],{"_key":496,"_type":68,"marks":497,"text":498},"5ea4c4dd51630",[],"My own workflow involves grabbing a single set of usernames and dumping them into a TSV I name that TSV after the security Group I intend to populate. Defining my path with the string below lets me change only 1 variable with each pass of the script.",[],true,"2014/09/17",{"_type":53,"asset":503},{"_ref":504,"_type":56},"image-40b24ef80acbd2a54b431cbfb6eb751a95c12a18-800x519-jpg",{"code":506,"language":507},"\u003Cp>Often automating a task is \u003Ca href=\"http://xkcd.com/1205/\">not worth the time\u003C/a> and rarely takes \u003Ca href=\"http://xkcd.com/1319/\">the time planned\u003C/a>.  At StackExchange we have lots of people on our team and in our community \u003Ca href=\"http://stackoverflow.com/tags/powershell/hot\">who are amazing at Powershell\u003C/a>. \u003Cstrong>I am not one of those people.\u003C/strong>\u003C/p>\n\u003Cp>\u003Cem>Is it possible to save time using Powershell, even if you're not a guru?\u003C/em> \u003Cstrong>Sure!\u003C/strong>\u003C/p>\n\u003Ch1>Framing the Problem\u003C/h1>\n\u003Cp>At Stack we use \u003Ca href=\"http://www.google.com/enterprise/apps/business/\">Google Apps for Work\u003C/a>.  Google Apps for Work includes a great tool for linking your existing Active Directory structure to your Google Accounts.  That tool, \u003Ca href=\"https://support.google.com/a/answer/106368?hl=en\">Google Apps Directory Sync\u003C/a> (GADS) allows a company to sync Active Directory Users and Groups with Google email accounts and mailing lists.  We already sync our users with email addresses, but my task is to also link our security groups with email distribution lists.  \u003C/p>\n\u003Cp>\u003Cimg src=\"http://stackoverflow.blog/wp-content/uploads/2017/02/s8lWuF5.png\" alt=\"\">\u003C/p>\n\u003Cp>In a fresh environment, this would be incredibly easy.  However, we have a number of mailing lists that exist on the \"Google side\" that don't have matching security groups in AD.  This issue is compounded because when group sync is enabled in GADS, any group that does not match an AD group will be deleted on the Google side.  As a friend put it:\u003C/p>\n\u003Cp>\u003Cstrong>We need to attach a trailer to a moving vehicle.\u003C/strong>\u003C/p>\n\u003Ch1>Steps to resolve the problem:\u003C/h1>\n\u003Col>\u003Cli>Match existing AD Security Groups to Google mailing lists.\u003C/li>\n\u003Cli>Generate AD Security Groups that don't exist for matching Google mailing lists.\u003C/li>\n\u003Cli>Populate the AD Security Groups with the correct users\u003C/li>\n\u003C/ol>\u003Cp>If you're familiar with GADS, you'll know #1 is pretty easy.  Using an AD filter we can \u003Ca href=\"https://www.google.com/support/enterprise/static/gapps/docs/admin/en/gads/admin/config_group_sync.html\">match groups in our AD structure\u003C/a> to existing Google Groups. The only concern here is to make sure that the AD groups actually have the same users as the existing Google group, since no sync has occurred previously.  \u003C/p>\n\u003Cp>The second issue, Generating AD Security Groups that don't exist as mailing lists, poses a problem.\u003C/p>\n\u003Cp>Running a simulated Sync on GADS shows \u003Cstrong>80 Google Groups\u003C/strong> without a matching AD security group. \u003Cstrong>(That's quite a few clicks...)\u003C/strong>\u003C/p>\n\u003Cp>This is our first opportunity to use Powershell to solve our problems.  \u003C/p>\n\u003Cp>I start by grabbing a list of groups that aren't in AD.  GADS simulated Sync logs those groups in a way that is easily copy/pasted into a nice Tab separated format.\u003C/p>\n\u003Cp>\u003Cimg src=\"http://stackoverflow.blog/wp-content/uploads/2017/02/copy-csv.gif\" alt=\"\">\u003C/p>\n\u003Cp>\u003Cstrong>Now that we have the groups we can get them into AD:\u003C/strong>\u003C/p>\n\u003Cul>\u003Cli>Read the CSV into powershell\u003C/li>\n\u003Cli>For each group, generate a security group with matching name.\u003C/li>\n\u003C/ul>\u003Cp>\u003Cem>\"BUT I DONT KNOW HOW TO DO THAT IN POWERSHELL\"\u003C/em>\u003C/p>\n\u003Cp>That's ok.  Lets use our minimal knowledge, and Google to figure out how.\u003C/p>\n\u003Cp>A quick Google search shows a Technet article on \u003Ca href=\"http://technet.microsoft.com/en-us/library/ee176874.aspx\">Import-CSV\u003C/a>.  Reading Microsoft Technet articles is an art all its own.  These articles provide lots of in depth information on Import-CSV.  While more information is GREAT, we're trying to Get Things Done.  Let's CTRL + F to find relevant examples:\u003C/p>\n\u003Cp>\u003Cimg src=\"http://stackoverflow.blog/wp-content/uploads/2017/02/Import_csv.gif\" alt=\"\">\u003C/p>\n\u003Cp>We quickly isolate the example CSV import.  By dumping that import into a variable ($csv) we now have an object Powershell can manipulate.  Following a similar search and CTRL + F for \u003Ca href=\"http://technet.microsoft.com/en-us/library/ee617258.aspx\">New-ADGoup\u003C/a> we end up a short script:\u003C/p>\n\u003Cp>{% highlight powershell %}\n$csv = Import-Csv -Delimiter t -Encoding UTF8 -Header Groups -Path C:Usersdoboyle.STACKEXCHANGEDesktopgroups.txt\u003C/p>\n\u003Cp>foreach ($i in $csv) {\n$Group = $i.Groups\nNew-ADGroup -Name $Group -GroupCategory Security -GroupScope Global -DisplayName $Group -Path \"OU=GADS_Groups,OU=IT,DC=Something,DC=YourDomain,DC=com\" -Description $Group\n}\n{% endhighlight %}\u003C/p>\n\u003Cp>\u003Cstrong>So Close.. But wait there's more!\u003C/strong>\u003C/p>\n\u003Cp>Problem 1 and 2 are resolved, but we still need to populate those AD groups.  Many of the groups only have a few users, and are easily updated using the build in Active Directory Interface.  Some groups are larger.  So large that the existing AD interface would require \u003Cstrong>hundreds\u003C/strong>, or even \u003Cstrong>thousands of clicks\u003C/strong>.  If you think that's too many clicks, you'd be right.\u003C/p>\n\u003Ch1>Powershell can help!\u003C/h1>\n\u003Cp>Just as before, GADS simulated sync will return a list of users effected by a planned sync.  We can again pull that list of users into a TSV.\u003C/p>\n\u003Cp>\u003Cstrong>Lets modify our existing Powershell script to populate AD groups:\u003C/strong>\u003Cbr>\nWe match on email address, not AD username, so we need to find the AD user with a matching email address, and add them to the correct group. \u003Ca href=\"http://technet.microsoft.com/en-us/library/ee617241.aspx\">Get-ADUser\u003C/a> has a filter option, which accepts a string.  If we set the email address provided by GADS as the filtered string, we should always get the user we want.\u003C/p>\n\u003Cp>{% highlight powershell %}\n$Group = \"All\"\u003C/p>\n\u003Cp>$path = $(\"C:Usersdoboyle.STACKEXCHANGEDesktop\", $Group, \".txt\" -join \"\")\u003C/p>\n\u003Ch1>There's no Header in our TSV, so we define one as \"GoogleUser\"\u003C/h1>\n\u003Cp>$csv = Import-Csv -Delimiter t -Encoding UTF8 -Header GoogleUser -Path $path\nforeach ($user in $csv) {\n$email = $($user.GoogleUser.ToString(), \"@stackoverflow.com\" -join \"\")\n$user = Get-ADUser -Filter {mail -like $email}\nAdd-ADGroupMember $Group $user\n}\n{% endhighlight %}\u003C/p>\n\u003Cp>My own workflow involves grabbing a single set of usernames and dumping them into a TSV\nI name that TSV after the security Group I intend to populate.\nDefining my path with the string below lets me change only 1 variable with each pass of the script.\u003C/p>","html","2014-09-17T12:00:00.000Z",{"current":510},"i-can-powershell-and-so-can-you",[512],{"_createdAt":513,"_id":514,"_rev":515,"_type":516,"_updatedAt":513,"slug":517,"title":519},"2023-05-23T16:43:21Z","wp-tagcat-engineering","9HpbCsT2tq0xwozQfkc4ih","blogTag",{"current":518},"engineering","Engineering","I Can Powershell and So Can You!",[522,528,534,540],{"_id":523,"publishedAt":524,"slug":525,"sponsored":12,"title":527},"28e560af-f0aa-4d46-bd90-f435ad604aa7","2026-06-26T14:00:27.102Z",{"_type":10,"current":526},"paging-charity-how-can-engineering-leaders-avoid-becoming-bond-villains","Paging Charity! How can engineering leaders avoid becoming Bond villains?",{"_id":529,"publishedAt":530,"slug":531,"sponsored":12,"title":533},"4b22c2a3-3779-4966-93eb-5230391dbdce","2026-06-23T14:08:58.595Z",{"_type":10,"current":532},"your-ai-shipped-a-backend-that-boots-that-is-the-whole-problem","Your AI shipped a backend that boots. That is the whole problem.",{"_id":535,"publishedAt":536,"slug":537,"sponsored":12,"title":539},"5cf362e1-fe7b-45af-b69c-914731c6a052","2026-06-23T14:00:00.000Z",{"_type":10,"current":538},"the-2026-developer-survey-is-now-open-for-human-developers-only","The 2026 Developer Survey is now open (for human developers only)!",{"_id":541,"publishedAt":542,"slug":543,"sponsored":12,"title":545},"30b995f7-7cb9-4dd8-bf71-d0685940a32b","2026-06-19T14:00:00.000Z",{"_type":10,"current":544},"dispatches-from-o-reilly-from-capabilities-to-responsibilities","Dispatches from O'Reilly: From capabilities to responsibilities",{"data":547,"sourceMap":-1},{"count":548,"lastTimestamp":12},0]