Adding Aliases to AD with PowerShell

Adding aliases in AD is a VERY simple task.

You can just find the user via the ADUC (Active Directory Users and Computers), go to the ‘attributes‘ tab on them, find ‘proxyaddresses‘ and add a new record prefixed with smtp:. For example, you could add ‘smtp:firstname.lastname@domain.com

But what if you need to add lots of aliases to lots of people?

You can do this with just a CSV file and the right PowerShell commands.

First, lets start off with the formatting of the CSV file. This should have two columns, one for the samaccountname of the user and another for the proxy addresses. Proxy addresses NEED to be prefixed with ‘smtp:‘, separated by a semi-colon and all lowercase.

Here’s an example:

samaccountnameProxyaddresses
usernamesmtp:name@domain.com;smtp:name2@domain.com

Next, we need to build the correct PowerShell script. I’ll list the steps of the script below followed by the script itself:

  1. Import the CSV file
  2. Run through each item in the CSV and try to add the proxy addresses
  3. Output either a success or failure message

Once you’ve built both components, you’ll need to update the CSV path in the PowerShell script.

You can now run the script for the aliases to be created. It can take a while for the entries to show, for me it’s typically 30 seconds to 5 minutes depending on the size of the CSV.

Enjoy! ?

LAPS Winform

*UPDATE*

I have created the *final* iteration of this WPF form which can be found here

*UPDATE*

I didn’t like having to remote desktop into my domain controller and couldn’t figure out if there was a LAPS tool included in RSAT tools so I decided just to make my own and to add some extra features.

I wanted the GUI to look pretty much identity to the actual LAPS GUI. You can see the difference below:

You might be able to see that I  changed the “Set” button to say “Set and Update”. This was because I wanted the form to also attempt to update the group policy settings on the computer so that it would get a new password a lot quicker than the original GUI.

There’s not much else I can say, I will leave the entire script below for you to copy and paste. You will need to add the domain controller for your environment in the $domaincontroller variable at the top of the script. I have converted this to an EXE and run whenever I need it, never skips a beat. Let me know how you get on with it. Enjoy!

#ADDING FORM ASSEMBLY
Add-Type -AssemblyName system.windows.forms

#ENTER DOMAIN CONTROLLER BELOW
$domaincontroller = ""

#BASE 64 ICON
[string]$icon64 = "iVBORw0KGgoAAAANSUhEUgAAAEEAAAA5CAYAAABphkbpAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAB5kSURBVGhDpXt5cFXHne7j/TN/vKr33lRsa7lXV9KV7r3S1b1akcCAQWKXQEK7hAQICSTATjI1M37UeItdFY8dO2MncVyVpTLjmedZY7ABLYCIoTLl2PFCbLzFjrFjs9gGHmDQvn7v+37nHFkEucr2NPTtc0736e7f17+1++i/YXYaHeHPlJuBCeZJu2KaZtbNOLOqdT/FH5VeZpqcdt61ujH2MMn7KeVJNpni6xNeU7cPjjMxZc003jifaRhrM9O/+pxi/RTG7H3nHtNq6V67eXpKvXxx/RTrx6ZHeU1CxodZAteCMDHICXCo6TEONMFm+uXjKZdyTUoFidJEpt1BJidV2pXz3M0aUE91PW7Td/5Nqk6kijjLbDY7CxGVHggTzvh6U0BMTrv9zozv1Hv3M+N+Qb3lEQIwLDCuA2GI1XpBaI9rmpa9Z5rQNCdo8+OvSu/aS5qABtNERbwIdqG0fPzF5/F///5n+Nt77sQ9t/8VHn/oQez5x3/Eh2//ntUczSV8etopLXtgMHmc5hCkJOKskXNnAHxxvXEKuZLsBwzOxQljY2qlnmYGdQp1wJfcZ6pWGuPkNJSyjaPxVXrZ3pvCieMv4a927sDNkSyUpAaxNBxBWTQbpdGok8NRFAbSsLSkGN+57x6cPnfWuhofJ/juWEaTsu5nj/F1M0UQw1rc60Dg0JNs4czdaWzJe/B5EhDiWs1rXB0qqf04n5gOoPwOXsFt7W1YEIlgRXYOqmMFqApF0VJQiOUpATTk52NNRgYaeb8yFMaaggIsyM5GUSwb3/vufeyPq6hBvL49EJR1/3Wyl9TvoHTgdSBwFDX804HcB96tsqcHvFL1kxPiJHHMON5//TWsKMjHKq70yrR0bMyJozYliM2ZWajx+dCWnYW6QACt2RGsZ7klLxcbkgPYnBXH+tQMlKYH0VSxBuMjV9k3tYH1zfHGPY7UnL56aXO3C97PqRMEgpLaK3sU242j1dVCV6b8bJWcPGXKx5gY7756HEXBANbHYqhIC6KVhG9Ky8StJLCVhN6aE0NtQgK6cnJQ5/ehnaJRn5yMb0Vi2Jqcjq5QHFUEYnUsimXFBZgYFhDOIkgnONPSuF+ndGgw3TA2lzi4WngmXwOAFKU0tEOqVelnRmkJiFEMXr6AhVz9SrJ2eUoaOqL5aPGlojMjjJakFOyIRLExOQWdWVHUUyTayREt/hTcSnHZmJCMbcEQmnwBbI3GUZ6WgbWxXNRVrGXvk7QvjooWEUbI1yi9bCI7NKirPwVhlA1mgWDJAUErrDp15qyF049AmNG+RLdl3TqsicWxKiUV7Tn5aEpMwS4qPhG4iyvemOxDVzjbIZSKsoFAbM8ModWXgp3UHa28N4AI2NZoHlb607AoEjYdMU4u0Ez+lKCvmi1JrEbmFAeBMCvNvEkCTdbde8NFU/EmRHBGh3Bs716UZoSwLhBEB5Vg7U1+7BQAPj+2Z2WiwX8T2iMZBIAcwZVu1MqHs7CZOmM7dUNt0o3YGRNn+AhMBM3+VGxlPyvY36LMTAxcujCzDE5W+oqlR8M47+f2E8bZVC3c5L1gICi797Ig/D9BeysPUE6MlOHG0jKs5ITbIrloTErFruw4mpKS0RmlEky+CTvjESu3R7IpEoEZgDoiIdT6EtCZE0Yjyx1ZEXsujhFHtJGjykNZuHf37RzW8T8saS52/RWzCsnVwJzWQZ7irKSbax44yXvsKCmyKD3Kk2+eQGkogpZYPglNx04qwYYkH7ZlZVH2/QZEU1IiWZ4AJAawKxJHc2IyuiKZaExJNABUvyPLUZJSmvWslw5p9QVRT9NaWjIfI1PyPB0OtDQzP1Jm3DqLY62lsnNr3qa1441AGHbqrgWBciI9N5NmXXuX9j6Jd8RA3ODoil88/iMso2yvSyFrZ+WhOSGFhMRQRwCk/OqSkrCLsr4x0U/CYqYrbqVP0JKcaKJinJIdRXMSOYNlrY8cREAE1K5QDFXstzgrhJdPHL8eBJucltcl2pusPVN2kt6x94wI5oE5dYIImpVm3Vzz3E3iA4mC0N2ysYEmLY6NuQVkYa40RaGOLL0lHMLGAK0BZb4xMQldtAI11AnbCVBLog87MjKxKcWpr3frG/3UIQTI4YwIGhKSsJn9CoSf/+InHNUjziXavddsnH+ziFX2mntZz+Tgze02fwkQdOGygXSCeEKTaqiiVcjLp05I48pTF5DQrSRAfsD2LJpHlbQGum/LiZJDqByp/DaTwB3hMJUggaGoNBC4bXSrm1N8tCbSDRQNAlNBc7s4noO77v4bDi5KRKqWk1n6ymbiRZpOrc3VI9pp4t7zZ5xcoCCK6TpxmCFWadbNzKXXIUeZMY3sdH1ZKcqLCtBQWIBKeoBbtZIkVAA0+pKwjcqvSUqQZnIDCWyjjthEf+E2OlIbpTtoJRoJhEShWf5DmNYk4UZyQgg1NyVgc14hlsbjuOOO3ZyC5iky3ezNiT9aEHeNmFTvAnVN5vMpgjD4Ga+/DghKGlCZDz1XuWblCqzOjWN5Wio2cbIbSLhYXKzeHqLy4/2uKJUdlV47PcHqZN5T+7fRX9hOR6oxmdZAniRXvk3mNIX1OSE0J9NaRGOoZOB1C+t3m4VwiHWI1CI4c1Hhyb1TL4Il98py9pxg3N6jT4TRuZyl0Tmsg5tmP9e1OUo2qlAdR0dzPcrzqAcIRGWAKy6WT0owpdfkdxwlKTlp/wYC0iVrQVHYGaJypA6R31BPR0ou9AaayW2xCN9LoDINm4fZkp2LpdQ5P/7BozML4Fw4RDn6gBJt2bUCSmznaC6HQ5QtyeUf/QJx+DLWQR1ZO8vORB649w6U0tytSQ1Q5mO24ttyyOI0fxIJKblb5TLTSojFmwiQrIVc6a5wDs2plCNBpM7oYBRZlXSDtWtlsLU9MxsV9BwX0tz2Hz7o0G406keE/D/m027+kPmkm3WvugFO9fP9kRkihoZ099UVo/e+3bsBlCz3s0cPYSktQT1Zt5aOUCedmwbK/nYSJFHoouvbSvPXRc9PZlH+gRwp+QHN5IQuU6YB8yvq/EnoIAcJMPXTyOizPicPiyhmly6RKC25gUB2n/yY5SvA1acw/O4DOP/it3Duhe0YeO0vgI++zyaHWf8e213UC/LsnXdVjujnv8AJdu8+HGWv2owrK8jDGgZA26MF5hG2hcKOdaBOaCFnyFGSjtiZzeeJN1o02SLC6TnWJfiwk+F2A4ERYM3UGWrfwH42EaAV9EE2N9RySE2cxE9c5kS42uf24d3DnXhrzwqcfHohzhwoxNkD2fhoXw5O7inCez1VOPvyd/jOcb7zKQEgAm4XGJwLhC/pJ+ha2QtrHXU6hcceeciCnaqUDGyjgyOXV8quhUrvNnKIRKSNWr+Osi4P0mIKmsmNNH/bIznGGRZEkWO+mR1zgFQQxbC6kGL2ysvPcwGkzK6QiBMYevNevLd/GU7tL8K5nhgudIdx4UA6rh4M4PwBHy73hvHx/mx8uC+O9w9uIPsf4WTPcuIkXiAM6edrguBstLpA2BMvTWAhFWMVXedKsnBHNNchkNq/IYG6IUZHiSLSwSCpPkXBEwGg0pN/0OynSIgDEhPNajQl+AlYHOvSQlhJALdtbGLQp30FsvXE6xj/4+N485clONcbwbkDAZzbn4zhwwSg17m+0BvCR3sK8P4v83F2XxSnuktw4ul6Tvg3JIAiNcK4Yc4A6suaSBMqisCE015Z13r864N9iGUGUb1wASroGu9kMLUxkGoeYj1FYStd6FpfIh2qzx0kOVYCRFZEVkOAbCeQAmBdvBA3890rF8jKZuo+IAH/irf2leFUTx7OHQrhwtFMnDvsrP757iAJzsXp/mqKyi/JNL0YeuXbeL+7DO8+swgfHWtjH68TDIrT0Nf2E8gFDGImJ5wzCj3XWYHVj/GXrPHDxx5BdkYANfmFWEel1yFZlwtN3WAOlFxkioZFk3SMOqg7BICCKCnFzQRqTUqqAVBCZ+qV559ngCsrQBCm3yAhDTjdG8XZ7gyCkMmSq38wFZcoBp/0ZuGDvjVs28OVfp/zOcd3nsPIm7fjwwP5eGffQuDSXnbFuhFZjj8F4Uv5CVxunUPQQZLtHaG6lXpxLaUBoe3uR3/0MGJZGVhbmIv1lPHbqNwsPKbrLH9BSrGOfkIHdYBc5B0UkeqkG9HGck2aD5VUskVUhkcP9buDcwAdmoy9SA5Yaqt+sT8Tl8gJAwcycWV/KgaeDeDkgTAG376T7V5i+wFmznWKpnK8Fx/2lFCHkEte+y6fv016ZUKv4wTqBLnCGnQWANckqyO19LjGJ52wdlTzU52AUGaSZ9ZzpBs3F8VQwZWuIotvysqhy5yGLXSMVG6Kk+VTU9ESZ5uAD03xbKzOSGE0moqqpQtw+gOaNvVlKDNPDWDy1B6cfCqOyz034HyPD58dzMDAM+kY6U7Hxb4EfNATxsXjf8nGL/MdrrSAwClagr34YF8uzhzMw6v9HXxGszryEcvrFKNcYFIhM+JqfiPOJsAfu1FSPWfGFdcjSYE3z8lJcoLrP0zSP5+cGMZD37kbywvzUUSXuiyeh7K8ApTm5mNF4XwsLyjC0rw83EJvsygjHZVLFuHpJ37KjujITNP3U6fK6nLsLAb/8FN8QLYWwVf6/KYIr3az7E7GZ31J+LQ3g/WL6Tf8nH1I9rniOIyPf7MJn/Tk4OPePLze18Bn/0kQCA7TdZxgpzMCwc4OnfFnLtw8s8usUve8k5UYmXDecX7cNoTH8eOncLT/CHb/9e2or69F2YrlWL1yDVaUrURjYyPuv/9+/Pa3v3XeEQu7/r4iVRM15ekzGHr/J2T5AlzsTcZAXwCDBOFKTwo+6/URlAAu9QVxpieK033LMXSc/sF7j+DU0Wp8eLgYp55JxaeH5+O1nlp2RhCGzrD8KpwwO2tCLgDK01SoKr0zQC8Pjw6Z3pA/MaadbLVnkgs7QS6ZOR1z2Ui3AlNe/qS5YM6ZqFUYEh9j5PQ/4eQzxbi4n4T3pFP5B6281JuOC33pVJDpOEMgzvZm0zQW4AxF4HRPCGcOpeHcr4I42VuAE4doIaYoDkOyOHOCwFIDupNS1rSkK2weeqDSimnnsNNEQ3kclz49gyef+AWqaypx7/33GVFePx5uo1PDfE5fXvfKLgijLHWpd3TVVFuJHVtbcfDp/WQzOUnU9BPP4o/7b8ElOkUXe9Isf9aTgUvMF/oy8OmhdJzvZ0muuNKbZtzyafcNuNTvMwvyXncxTr94N2l9g9aDZpLpenHwZszsXWpl7IBzVp0mOsiJSjVOUWv/55FetJHwJbkx5FHDx3KjePjvvu+oklnvjJJyL6TVvZdFvPLnSnYC326qo5JMZ0ySjcU0m3d8azPOvvYTrnQZvcFMAkD2pzgMsrxKgi+TA8QNAuKT3lRrM3AwaKJzmebz3N4APthLffHpUxyUlmGAnifT3CB4AQQLu7VpurNjYWqD12L1f/nnJ1BanIebM9Owivb/Fk66rLgQuYwgn3zySfVi70jDewTbHqUtv9OlNIBCYO2Ce8ZJZ5rfbmpAGZVlfVEJlmf6UZo1D//24FL6BosdggmAgBjopnlkFiAX+lJx/lAQ58gVF3rYhj7E1YOO6Jzfl0//oolo/44D0nLM6TGOOg+dHSNdOMXMOol/x4QCcOhAD5aXFGMJo8J16enYTLNXHUhHS14hlgUzuXI5ONzd63AB2yv//t138NOf/wxnznzsKFcBQZ/jpVdexhP/9A8YHLhsz3W8qffuvetuWpJclPlTUZf55zj2wxW4eGQViQ1TEZJgEnmRq/1ZdwiX6SlqxS8eJNv3EJB+xhHkCpnRq4eSaE2y8M6e1cD5/+CYtApjdL7mjiJdP8FLs0GQxpbOGBxCZ0sLikl8VVERVsnFzYrZGaPi/hp/Ou39fCwJhnGsT2EsE/t56bnnECdY+XyvY0u707cUAr3PYvoJsVAGlpTkY/gq5ZR14ph7vnMfFrCulrkhcx6e+34YA/059BFSmP2mDC/3RUh8DrkiYpwgtr/URze6m+JyOEyxCDOizMa7Ty8DzvyC4/2emb6DDo9GxINzKUYmj3axva2iVmxyBH988WWszM3FEvr9VbT7cnTaGdw0JzMMpgvcmkgX2IKeCBanh/Dq8y+wrylcHbiExdQV6whMTVYuVt1cik8ucNXZ9cD5T7FYgM4vws2xGJpqapwxmR5//DGUxCNYFk5AbWwejj2SjMFnM8nelPcDfnIAc18InxwqwJVfLyZ3ZGOAgdOVA4wn9kdw6uko3npqAT44+k26ygdJx4fsm0GYwBdto3OB4HKCcarubbWYR4fxu18dQimjvNK0NDQWFGA1Xd1tnLSCoM5wyLbT5RprQ6UxJx9LGSK/9/YbpGcMDQ1VKKWy1CFrrT8DCxgm9/U/a3rgSG8vlqYHsTqYgfV0nOaHQnj04Yc4j0n85Mc/xM3xAFZH5+FXj5Vh6LlSnO9LsSjxKll9iKZv6NAC7LsvGT/e+T9x5AcxnOldT/O4Huf66zF8nMR/8jOOQkug6HOcFsajSUAPfcEJlJLaTLhHbWp87g+/x7KsTJQy2JGrq42OnXSBdbi6lUGRzhW0i1zr92NzLJcApWEZAfvw/bfxo8cfQn40HVXFBahmtLglJw8LyTUPfO9B0zQPfe9+LM+Koo7vrQ0EUFtUiGhmGK++9jr+jaZ2eex/4Xub/geGj67AJwei9AiDuHwoFRcZPI0dXoL+O4KMTuehMfYNLI39b2xYHeYq/4HzPsn5y+1WfPAZF9YJ+PSR2AwIc265zwJBqsF8H7JFfelSlDIqbI7H7eDk1kgOtiT6HQ5g9LctK4wGRodtBKKKQDXF4ihnSPzoXbuxKBbG+uJ8AujDZr6v6HAJOeiFF35DTpjCiy++gALqCnFYWywH6wLJWD0/hvJbYrh9SymeuHMRho+tpQkki1MBXuxjbMBy4mgpjtyZgXbqiltjaVhL5bmqqBgF8VzcufsuI0I0iBaRIYukayUrBcbYXNZBJpJJ/r8lFn179mIZlVZ9LBvVFgZHTQdo11hhsfYEG3w+JxzWuQLrBUQDOaE6PQNbyTmVvgA25+q4PgUrs0K445u3OZPkEDK1f3P7/+Eq6oCFUSXZvzJjHu6q9+PoDxbgnX8tpAhEufq0/c8k0zWOYuJQGY7sDmJr+jx0ZFJfJNxAUSNwqeS4ghLkZkbxx5PkAMk9s3SbQxH9GoqEufHyigfm3G12QPDSJA13ZVkZqkhARUqynSjpg4ouEirCBchGsnA7Q15POWqLbFtOFI18rg8umhMImEWNqahh+LwqNwcnT7zKiX0+1u9eehHFkUzUM4iqTPkz3FuVhKv9bXR2FuLKQa68bL8cokPZGDq4BM9/Nw9tgXnYlZNiGzC7yHk665SOWhtIw/LcAuz+9l87IIjtiYBodnnCKRkBz20d5CfwBXGCXnrrjTdRkp1NVk7BVilBbX5yxXXavEMDUyQ6Ilm2M7QjmmNbaDv15UmyTp9DtlusQ9bqZL/pgoq0DOysqDRF67jbHHOMJe/XFOTZV2yVMR9+0EVnp7+cfkCMTk6qRYoDPRF6f4vxwsOF5MB52BlPQ03CN4wD9R2D5qPt/dZoJpZzAVbn57N/eqXMTgDH5AJiIEjW5z6VnuUnsHjg7nuwjGzarI+q7HA0ZLvGIrze9Q+kJPVliYDRWaM2SLqkLBMTsCvscE4b66sCQdSEY+gqryLK7qQkl3IlR67iluwAKuI+VObMwyPb/zsuPbvYYoHPulMwdCCMib5b8NuH8tASpAhk+ezQt5PA2+EtdZR2rrRNX5eaZPsTyzKDONbfQ2ZwXHTTCPov7jBx4LhznkqPSzF6E5zElrVrUUVO2GBni96HFtm2jb7NjtREuD64kIg4R2x2mkwgOgVAog+3EihxTFuswL5iaxcniAuFtVmgCQ41iNL5N+HY42vx0b8vxqk9cbJ/GFcOMwjaH8B03xKceLAIreSArmgiOTLBrJOdWFE36QxTgOheBz+rA6n2neS9d+4m+eP852zUG2nKNrbAn0sc3C9V1AbDQ1hCrV1Oh0gd69uizlwCkniDmUMRrDNC74sS+QmdUZo6f5JtojZQJGzbXOcJWXSpaTY3kGXbK8kJHH9aeJvHeIkX76CmdB5O71+CEXqAg/3ZtABBC5Mn+hfi9UeKsdlPEYgm2UGOtuWle+xDjhS/c2DDe51g1VA0mvPysZp1tWtXiigDwEAQYbNBoPerdB0nqF75rVeO25endZx4dUqQiFO5udvmOiCxs0VxAr29zQRIE6tPcj65qfclcMXCBIAiJKWZ5DftvSo9FVvXrqEe4ACcjCOrJ/GHX3fizK+WUAdkMwZg3H+AcUF3GGMHb8YbPy5BE63FlmxaAf+N6IxR9AjwjhznTFN+Ssus7x/EoToVby6ej5JQkIPoOyyJhADncELDA2FoTuswZgpVjlL3L/cyOArZ9wZtOQWU9SC2UfYkg/qCRN8NyE+QstwRznLODOUv+BNs07Q+6SbsonJsJWA6YKmjddhA32FXFTlB4SL/S1KBt/F293KceYbxAGP/y4z6FBCN9i/DG48tRGvaPHQWUFekJNhhrZ1oiWD6J/rWSePp0FffP2geWpitFM1yLsyi9ABOvXlChFH9uIpYQ6qU6LsB47UgUGMLKAHx6N8+gLJwmFFhARrTQqZ8mijj0vbyFE0J2rkBS660zg0EUEc0Qs+QE6NfIYC0u9zECUmkxAlb1jKSo0UYY6gshtAB6tljW8wSXKElGDyQjqnuBXjv8SU0v1SCFIHq5D9nf9qmT3TPKqkLqKNmf/+gBdHJlR3cJOrzvzhWZ2TiuWeeJtoiltQb8fzxOGFwrqP5yVFbHXlXf9G5HVX08Mq54u1SQonJjvmjzMtPkF2Wn9Ci7xXp5jrfF1AO2X4bAdABi9rpXEEcVENltYH3XVVUjNTMAtos1OQZTL/zIE49tQiDhxYxHrgFp362DG2mBJPNFRfLN9OR0ja9xhHL14jDqIRb2L/3/YP3Qag82np/mn0M+uRDDxN0x2U24r38hZwwJm9KdnUCW6qrUBFMpQxSu5PgLq5Eo59KMZzunDLLGhAYzzrsohKUrtDEnK/VKLvUCfowQ4et7TmOy9xZXs6VobJyT68wzcDm3F68+c/12HNHHL/+u3XYSBHoCH+DBN5ost9KANu4qvqOQZ/81ukQV9aAOkCcKNEQ54lTTFRljUJZqKQ4P3K7nCbnI1XPMtvA4oQ5QRgfZr2YdBxrF5VgIz0/EabDUzki7RFqXsqmBpJfICDkKNkXqhQV3cuTlGcpVlU7Pfe0dgM5amfFOgNBE7ENrEkdrr6OKsYA1cx1BKAtK9UIco7vE+xTniZ/un3HoEPaTvknSSlmJmWdJBo1/kQ745So6Li/gYBXc/y/bG7iQLJ6MpReIhqmGOe0DtKWfIHIlS8soTJKtZVuJPKyw/ryRCujFZB5lP0XgfUs9X2BSrUTq2qlpAvaqSvkULXn5GJ9IB27yis4hGOGbVKK7oY/RnM+nSkqOemcJrL0bSS0OSHJPuSoS9TK59q4M/WROFpuEus7oqlPgPSJkEo5ThqvnCF613qCru+TJOgWEUosKIxfyAljQ2QZV4lwtapjefat0JaCYvv8vpXmsoKEbaEdXseyhfXrg/QOyepqp8/sKmieWvLyzL9opihVBYNoZRC1kh7mhtx8bC1fzwlwBCJgf8WiDZvBAZSR3Rui7M+voKsIVT5ZJXIQ+20mQXK5NzG2WCcXnv2p3vYnVE/C1wQDaCxkkJYWwEbNMy2ICuoQixRJ/Chd8xnkNa64cU4TSS0qeyq8RvUHIGo4QvEYYtbeop7J11ccLmWjgEsKRqVQ1Wdxytq/0zH6BEtpZh2D69xBKyGibQR5iqyX6dIYMpvjaqf33T6VNY49U998T1ljqY2e6Y/XVK+xtIC61jPtGhkNRJyEG9fxZ1z7+roxENiO6VoQ2LnUlao4hLU1FtKF3fDHrjlhgqU4w2mjFdWFBpTed5SryhnOYhphO0mm/tBsalKjcKKqc16xts7X0nbLGrXWt0aOw2PjaRxLfM/d/1OQ5CyeezSg+Yh4NZlw5qiW9qp+FLMIhDl3m4c5MTbSC9r/l7lU5/YeX7ROlHTBPIOJe//5SF7BTpR4o8mImdTEnttRGxPrHBdaN854aiMQxrkcExhmKSdOIKhG77JQdieg8XWrd1QqeXsiYhw9d/pz6zUtVczJCQJBCGq2ai3W1QxV2sYjS7HnKJ/pXoiqQ2/Wo7ywkvVaDYXLaqc/uNJz5imxvp6LlfWesmanTK6bpl4yNla/xkVeZgOJmvrzxjd2Z6m+rR/+2Htu9voxWpj1js2L2cRc/QL/H9J7FoQajQSGAAAAAElFTkSuQmCC"

#CONVERTING BASE 64 ICON TO SOMETHING USEFUL
$iconstream = [System.IO.MemoryStream][System.Convert]::FromBase64String($icon64)
$iconbmp = [System.Drawing.Bitmap][System.Drawing.Image]::FromStream($iconstream)
$iconhandle = $iconbmp.GetHicon()
$icon = [System.Drawing.Icon]::FromHandle($iconhandle)

#LAPS UI FORM
$lapsform = New-Object system.windows.forms.form    
$lapsform.Size = New-Object System.Drawing.Size(400,320)
$lapsform.Text = "                                     LAPS UI         "
$lapsform.StartPosition = "centerscreen"
$lapsform.FormBorderStyle = "fixed3d"
$lapsform.Icon = $icon

#LAPS TEXTBOX LABEL
$lapsform_computername_textbox_label = New-Object System.Windows.Forms.Label
$lapsform_computername_textbox_label.Location = New-Object System.Drawing.Point(20,20)
$lapsform_computername_textbox_label.Size = New-Object System.Drawing.Size(100,15)
$lapsform_computername_textbox_label.Text = "ComputerName"
$lapsform.Controls.Add($lapsform_computername_textbox_label)

#LAPS TEXTBOX
$lapsform_computername_textbox = New-Object System.Windows.Forms.TextBox
$lapsform_computername_textbox.Location = New-Object System.Drawing.Point(21,40)
$lapsform_computername_textbox.Size = New-Object System.Drawing.Size(250,15)
$lapsform.Controls.Add($lapsform_computername_textbox)

#VARIABLE FOR KEYDOWN
$lapsform_computername_textbox_keydown = {}

#KEYDOWN ASSIGNED
$lapsform_computername_textbox_keydown = [System.Windows.Forms.KeyEventHandler]{
    if ($_.keycode -eq 'Enter'){
        $lapsform_search_button.PerformClick()
    }
}

#REGISTER KEYDOWN HANDLER TO COMPUTER TEXTBOX
$lapsform_computername_textbox.add_keydown($lapsform_computername_textbox_keydown)

#LAPS SEARCH BUTTON
$lapsform_search_button = New-Object System.Windows.Forms.Button
$lapsform_search_button.Location = New-Object System.Drawing.Point(290,40)
$lapsform_search_button.Size = New-Object System.Drawing.Size(60,20)
$lapsform_search_button.Text = "Search"
$lapsform.Controls.Add($lapsform_search_button)

#LAPS SEARCH BUTTON LOGIC
$lapsform_search_button.add_click({
    if ($lapsform_computername_textbox.Text.Length -le 0){
        $lapsform_output_label.Text = "You must enter a computer name"
    }else{
        try{
            #getting text from textbox
            $computernametext = $lapsform_computername_textbox.Text

            #checking if computer is in AD
            $checkad = Get-ADComputer -Identity $computernametext
        
            #invoking admpwdpassword command on $domaincontroller
            $invokegetadmpwd = Invoke-Command -ComputerName $domaincontroller -ScriptBlock {get-admpwdpassword -ComputerName $args[0] } -ArgumentList $computernametext | Select-Object Password, expirationtimestamp
        
            #getting password and password expiration date
            $lapsform_password_textbox.Text = $invokegetadmpwd | Select-Object -ExpandProperty password
            $lapsform_password_expires_textbox.Text = $invokegetadmpwd | Select-Object -ExpandProperty expirationtimestamp

            $lapsform_output_label.text = ""
        }catch{

            if (!$checkad){
                $lapsform_output_label.Text = "Computer not found"
            }
            #clears password and expiry textbox
            $lapsform_password_textbox.Text = ""
            $lapsform_password_expires_textbox.Text = ""
        }
    }
})

#PASSWORD TEXTBOX LABEL
$lapsform_password_textbox_label = New-Object System.Windows.Forms.Label
$lapsform_password_textbox_label.Location = New-Object System.Drawing.Point(20, 90)
$lapsform_password_textbox_label.Size = New-Object System.Drawing.Size(100,20)
$lapsform_password_textbox_label.Text = "Password"
$lapsform.Controls.Add($lapsform_password_textbox_label)

#PASSWORD TEXTBOX
$lapsform_password_textbox = New-Object System.Windows.Forms.TextBox
$lapsform_password_textbox.Location = New-Object System.Drawing.Point(21,110)
$lapsform_password_textbox.Size = New-Object System.Drawing.Size(250,15)
$lapsform_password_textbox.ReadOnly = $true
$lapsform_password_textbox.Font = New-Object System.Drawing.Font("courier",12,[System.Drawing.FontStyle]::Regular)
$lapsform.Controls.Add($lapsform_password_textbox)

#PASSWORD EXPIRES TEXTBOX LABEL
$lapsform_password_expires_textbox_label = New-Object System.Windows.Forms.Label
$lapsform_password_expires_textbox_label.Location = New-Object System.Drawing.Point(20,145)
$lapsform_password_expires_textbox_label.Size = New-Object System.Drawing.Size(100,20)
$lapsform_password_expires_textbox_label.Text = "Password Expires"
$lapsform.Controls.Add($lapsform_password_expires_textbox_label)

#PASSWORD EXPIRES TEXTBOX
$lapsform_password_expires_textbox = New-Object System.Windows.Forms.TextBox
$lapsform_password_expires_textbox.Location = New-Object System.Drawing.Point(21,165)
$lapsform_password_expires_textbox.Size = New-Object System.Drawing.Size(250,15)
$lapsform_password_expires_textbox.ReadOnly = $true
$lapsform.Controls.Add($lapsform_password_expires_textbox)

#DATETIME PICKER LABEL
$lapsform_datetime_picker_label = New-Object System.Windows.Forms.Label
$lapsform_datetime_picker_label.Location = New-Object System.Drawing.Point(20,200)
$lapsform_datetime_picker_label.Size = New-Object System.Drawing.Size(150,20)
$lapsform_datetime_picker_label.Text = "New Expiration Time"
$lapsform.Controls.Add($lapsform_datetime_picker_label)

#DATETIME PICKER
$lapsform_datetime_picker = New-Object System.Windows.Forms.DateTimePicker
$lapsform_datetime_picker.Location = New-Object System.Drawing.Point(21,220)
$lapsform_datetime_picker.Size = New-Object System.Drawing.Size(250,15)
$lapsform_datetime_picker.Format = "custom"
$lapsform_datetime_picker.CustomFormat = "dd MMMM yyyy"
$lapsform.Controls.Add($lapsform_datetime_picker)

#DATETIME PICKER SET BUTTON
$lapsform_datetime_set_button = New-Object System.Windows.Forms.Button
$lapsform_datetime_set_button.Location = New-Object System.Drawing.Point(285,220)
$lapsform_datetime_set_button.Size = New-Object System.Drawing.Size(91,20)
$lapsform_datetime_set_button.Text = "Set and Update"
$lapsform.Controls.Add($lapsform_datetime_set_button)

$lapsform_datetime_set_button.add_click({

    if ($lapsform_computername_textbox.Text.Length -le 0){
        $lapsform_output_label.Text = "You must enter a computer name"
    }else{
        try{    
            $datetimepickervalue = $lapsform_datetime_picker.value.ToString("MM dd yyyy")
            #getting text from textbox
            $computernametext = $lapsform_computername_textbox.Text
    
            #checking if computer is in AD
            $checkad = Get-ADComputer -Identity $computernametext
            
            #invoking admpwdpassword command on $domaincontroller
            Invoke-Command -ComputerName $domaincontroller -ScriptBlock {reset-admpwdpassword -ComputerName $args[0] -wheneffective $args[1] } -ArgumentList $computernametext, $datetimepickervalue 

            #setting value of output label
            $lapsform_output_label.Text = "Password reset request was successful - GP updating - PLEASE WAIT"

            Invoke-GPUpdate -Computer $computernametext -ErrorAction SilentlyContinue

            $lapsform_output_label.Text = "Finished"
        }catch{
            #checking if computer is in AD
            if (!$checkad){
                $lapsform_output_label.Text = "Computer not found"
            }else{
                write-host "Another issue - WinRM probably isn't allowed..."
            }
    
        }

    }
})

#OUTPUT TEXTBOX
$lapsform_output_label = New-Object System.Windows.Forms.Label
$lapsform_output_label.Location = New-Object System.Drawing.Point(1,265)
$lapsform_output_label.Size = New-Object System.Drawing.Size(385,20)
$lapsform_output_label.BackColor = "white"
$lapsform_output_label.BorderStyle = "fixedsingle"
$lapsform.Controls.Add($lapsform_output_label)

#LAPS UI FORM DIALOG
[void]$lapsform.ShowDialog()

Better Credentials Checking in PowerShell

This is something that I have recently created so that when a script asks for a credentials and there is an error, it doesn’t display a big, ugly and often intimidating error message for any poor soul trying to run my scripts.

That’s why I have recently (as in yesterday) “created” a “fool proof” way of entering and validating credentials against a domain.

This was a problem because whenever someone ran my script and did ANYTHING other than enter perfectly correct credentials, it would throw and error and exit the script. Or even carry on with the script WITHOUT THE CREDENTIALS, which obviously wouldn’t work. I know, I know. Amateur hour! But it was a crap system I must admit.

That’d why I spent and hour or so creating this beauty! It captures any errors, such as null credentials and incorrect credentials and only continues if a user exists with the same samaccountname as the one entered at the credentials prompt and if the user is in the domain admins group. Just for added “security”. Really I just want the appropriate people to be using the script.

This is the code I use!

#PROMPTING FOR CREDENTIALS
$cred = $host.UI.PromptForCredential("Need credentials", "Please enter your username and password.", "", "")
if ($cred -ne $null -and $cred -ne ''){
 #CHECKING IF THE CREDENTIAL USERNAME EXISTS
 $check = $(try {Get-ADUser -Identity $cred.UserName} catch {$null})

  if ($check -ne $null){
  #GETTING CREDENTIAL USERNAME GROUPMEMBERSHIP
  $checkadmin = Get-ADPrincipalGroupMembership -Identity $cred.UserName
  $checkadminrefined = $checkadmin.SamAccountName
  #PUTTING GROUP MEMBERSHIP INTO AN ARRAY
  $array = $checkadminrefined
  #CHECKING IF USER GROUP LIST CONTAINS DOMAIN ADMINS
  if ($array -contains "Domain Admins"){
   Write-Host "Credentials are GOOD! - Continuing with script" -ForegroundColor Green
   Start-Sleep -Seconds 1
  }else{
   #RESULT IF USER IS NOT DOMAIN ADMINS
   Clear-Host
   Write-Host "Credentials are not a domain admin! - Close and start again" -ForegroundColor Red ;
   $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
   Exit
  }
 }else{
  #RESULT IF NO USER CAN BE FOUND FROM CREDENTIAL USERNAME
  Clear-Host
  Write-Host "Check is empty - No user found matching credentials supplied! - Close and start again" -ForegroundColor Red
  $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
  Exit
 }
}else{
 #RESULT IF PROMPT IS CLOSED / NO CREDENTIALS SUPPLIED
 Clear-Host
 write-host "No credentials supplied - Close and start again" -ForegroundColor Red
 $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
 Exit
}

You should be able to read the script and see which each part does. I left comments in the script which I don’t normally do since it might be easier for you to see what its doing with pointers at each stage.

Enjoy!

Resetting pwdLastReset Attribute in Active Directory

This sort of thing is useful if you have a bunch of users that have passwords which are set to not expired, but then you decide that they do need to expire. But if you simply untick the “Password doesn’t expired” attribute then it will instantly make them change their password because the “pwdLastSet” date will be from when the user was first set-up.

This trick will set the “pwdLastSet” date to today so that they have some warning before being told to reset their password.

First of all, make sure that you have “Advanced Features” turned on from the “View” menu.

Now find the user that you want to reset the value for and edit their properties. Navigate to the “Attribute Editor” tab and scroll down until you see the “pwdLastSet” attribute.

Edit the value to be “0“, this means that the value has never been set. See screenshot below.

Changed to 0

Now click okay on all of the boxes until the users properties window has closed. Now reopen the users window, go back to the attributes editor and change pwdLastSet to “-1. See screenshot below:

Changed to -1

Now press okay to all the boxes until the users properties window has closed. Now when you check for the pwdLastSet attribute it will be set to the current date.

Hope this helped you, enjoy!