security

Bypassing Windows 10 UAC for Unknown Publishers

Bypassing Windows 10 UAC for Unknown Publishers

It happens that some programs alert you in Windows 10 about Publisher: Unknown and expect you to possibly provide administrative credentials to even execute it.

Especially in corporate networks users likely don’t have this level of permissions and surely the IT department respective IT-Administrators going to be reluctant to grant administrative privileges when they are not absolutely necessary.

For this specific case, there is a possible workaround – try to start the program with the following CMD-command and see if you might be able to bypass this issue. I sure don’t recommend doing this just for any program, be sure that what you want to start is safe, but there are cases where this is necessary, cause you won’t want to alter the UAC (User Account Control) or permission level or the employee.

Of course, adjust the path to your program. Eventually the parameter __COMPAT_LAYER=RUNASINVOKER is likely to bypass this specific issue.

Note that this also depends on a few more variables, but it sure is worth a try.

Auditing network users against HR lists etc.

Auditing network users against HR lists etc.

Auditing network users against HR lists – a topic that is often overlooked or causes some headache due to e.g. name variations, while it is so important to make sure that your Active Directory is a clean and up to date as possible.

There are big paid solutions out there, but unless you have the budget, resources and processes in place, you will need a simpler approach. Having worked in various sized businesses, let me make some suggestions here. Keep in mind, not all of it might be applicable or best for you, but I hope it will at least provide you some ideas and help to improve your network security.

Structured groups and rights

Before we begin – you should always make any effort to have a very well structured rights base. Avoid cross use of e.g. groups for mail distribution and NTFS file system access. It seems like a good idea until someone needs access to the NTFS path and boom he/she receives the group based communication as well. This is of course just one example. Structure your file systems and right assignments well. All of it can make all the difference. Don’t complicate things, keep it simple.

Monitoring Active Directory activity

What you want is something that constantly looks for any changes to Active Directory, at a bare minimum new users and deleted users as well as group-membership changes. There is some software out there to do this, some is free, often with limited functionality, some you need to buy. Personally I was working on a Windows Service to monitor Active Directory changes, but my time is limited and to this day I did not finish it. Having said this, the IT-Asset Management Database on this website actually has a module that does just this, it monitors the most important activities while it does actually a compare of gathered SQL data against current Active Directory information and eventually sends you a daily report about changes.

Such reports might not be perfect, as they don’t real-time monitor such activity, rather then only send you daily summary reports. Paessler PRTG in combination with either some default sensors or custom scripts like Group Membership change and password reset monitoring or the more specific script for group-membership monitoring are more then helpful. Monitor especially e.g. Domain Admins groups and other groups that would allow access to sensitive areas and data of your network. Such active alerts due to a network monitoring solutions might give you the chance to act fast.

Auditing your user base against HR (Human Resources) data

Again, there is software and solutions out there that can do this automatically or help you with your efforts. But often HR is simply using their Payroll platforms and depending on what they have, it won’t have the functionality you need or they are reluctant to implement such processes or possibly provide you access after all.

The main issue I came across is that there is a difference between the HR data and what the full name in your Active Directory (e.g.) is. You can’t further not just automate user name prediction based on any HR export data you have, cause there likely will be duplicate names as well, depending on how you create user names.

HR normally has an employee number, they should be able to provide this in any employee export to you. Now, Active Directory has actually some attributes that you easily can engage: EmployeeID, employeeNumber and employeeType. PowerShell is your friend, if you want to set them. I highly recommend to use PowerShell to some extend if you create new users. Look at the CheckLists in combination with employees in the IT-Asset Management Database as well for some hints and automation. Microsoft’s Set-ADUser PowerShell command will be helpful as well.

Eventually use a tool like the IT-Admins tool to read your users from your Active Directory and export to Excel. Once you have this, you compare the HR list against the Active Directory export. Don’t bother with VLOOKUP – research the use of INDEX/MATCH in Excel. Format both tables as tables in Excel and document your process, as this might depend a bit on what tools you engaged and how the eventual data looks like. You should end up comparing the HR employee number against the HR employee number stored and exported from Active Directory. This should give you a quick and clean overview. What you should be on the lookout for are those N/A error in Excel in the compare column, as well as possibly HR data that indicates a termination or change. You can go as far as compare the department information, again there are Active Directory attributes for this as well. Department names and department IDs.

If you want to go another step, start comparing group-membership as well. Export all the groups and members, again the IT-Admins Tool can help you here. View it possibly from both sides, the group and members view as well as user is member of groups view. Have the department owners take a look at it as well, they might want to see this.

And step three will be an NTFS rights review. Never ever should there be a user account directly used to assign rights in NTFS. This always should be done via groups. How ever, to review this I again recommend using the IT-Admins Tool, as this is actually designed to help you with the process and is able to export the needed data rather quick and simple.

Don’t forget your ERP systems and systems with Active Directory independent user bases

It is not always possible to rely on Active Directory as only source for your user base. Even if you can, the right assignment in e.g. your ERP system to functions likely is independent from Active Directory. Look in to any possibility of your ERP, either API’s or possibly dig in to the database (or where ever the data is stored), to find out about right changes (groups) and review those lists as well against HR information periodically.

Office 365

Oh – it is synchronized with Active Directory, right? Well – review it anyways. There might be a user object that is not synchronized and exists only in Office 365, groups as well. Review the rights to access certain administrative areas within Office 365.

You should definitive review third party users – especially Microsoft TEAMS and sharing e.g. SharePoint or OneDrive files and folders with outside of the organization will likely create some guest accounts. Keep an eye on those.

And then the third party applications – you need to keep an eye on those, as they can cause possible harm or gain access to sensible data. Users/Employees often will install them without reviewing them thoroughly, or they simply don’t realize they might have been there and share confidential data.

Account breach / compromise and API keys in Office 365 should also be something you want to keep a good eye on. Clicking on the wrong link (it will happen!), entering the password and it is to late. Don’t think a simple password reset will solve the issue. Don’t only rely on your MFA. Review does API keys especially in Office 365. What can happen is that the password is used right away to install an API based access to Office 365 that will then independently from password changes have access to the data. Keep an eye on those things as well!

 

PRTG and Cisco ASA VPN monitoring

PRTG and Cisco ASA VPN monitoring

The default PRTG sensor for VPN connections on a Cisco ASA has a limited of 50 users connected, actually less. This is due to the limit of 50 channels per sensor.

These days IT departments everywhere likely exceed 50 VPN users everywhere.

Since I do not need to know who is connected, rather then the amount and load on the FW, I came up with a simple sensor and MAP in PRTG to show me the essentials.

Add a snmp custom sensor to your FW in PRTG and use the OID

  • 1.3.6.1.4.1.9.9.392.1.3.1.0

This will give you a number of VPN connection. I am not 100% certain about the OID only being used for Cisco AnyConnect or other VPNs as well. I found it as a valid SNMP OID as I only use Cisco AnyConnect and my VPN tunnels aligned with this number.

Further did I add sensors for CPU / RAM and on the external interface of the FW to the map in PRTG to see the overall status and load.

Detailed information on the bandwidth are a different story, since this is more a passive point in time configuration, I don’t pull that in this map – I care about an average load picture not single pikes that only are temporarily. For this I have different approaches and sources. Mentioning this only for the big picture and cause you need to be aware of that.

Hope some find this helpful.

If you want the users that are online and offline – what is actually a big of a questionable thing due to data privacy concerns and a user not always needing to be on VPN in order to do work – you could create scrips to access more detailed SNMP data and balance this in various sensors. This is possible, but I do not recommend it. Another approach would be using the TEXT value in XML sensors and put the info there. Still, I think you might get to much data and need to ask yourself if this is even something you should collect/monitor.

Here a picture of my map as we barely started getting more home office people online.

PRTG Cisco ASA VPN users

PRTG Cisco ASA VPN users

Backlink to the Paessler PRTG KB, where this was discussed as well: https://kb.paessler.com/en/topic/64053-my-snmp-cisco-asa-vpn-users-sensor-shows-a-user-limit-error-why-what-can-i-do

Search the Windows Security Eventlog for a string / text

Search the Windows Security Eventlog for a string / text

Lately I had to search a lot through logs – as you can tell by all my postings… I just had to create yet another script that allows you to search through the Windows Security Eventlog – while the script is easily adjustable to other log types like application log or system log.

It’s not the most pretty script – but it certainly works. Don’t be surprised if the script takes it sweet time – it might be it needs to read through a lot of eventlog entries.

 

Active Directory password reset events and group change events

Active Directory password reset events and group change events

The script below uses the security event log on defined DCs within your Active Directory to export events related to certain activities. Eventually the script will export this even to an email and send it to you as a report – if needed.

As is – the script will specifically look for those events

  • 4724 – a user password was reset by an administrator respective via Active Directory Users and Groups MMC (or similar)
  • 4728 – a user was added to a security group
  • 4729 – a user was removed from a security group

There are more events – specifically events related to adding/removing users from distribution groups etc. – for the purpose of for what I wrote the script, I did not need this. Still, I thought it is worth publishing this, as others might find it helpful.

To add more events – just adjust line 19 – eventually just add more “or EventID=1234” statements – should be rather easy… in theory you could build that out as a parameter as well and inject it via the script.

 

APC network cards – fix logon issues

APC network cards – fix logon issues

APC network cards – or the NIC of many APC devices like UPS and A/C – possibly even NetBotz (APC – aka. Schneider Eletric) tend to have an issue that the system is telling you in the browser that there is already a session active.

The reason is that they tend to keep the session online forever, if you don’t click on logoff before you close your browser etc.

What you will see is an error like this after you entered your valid credentials:

Notice
Someone is currently logged into the APC Management Web Server.

Please try again late

It is actually pretty easy to bypass this – you either use TELNET or SSH to logon to the system with the same credentials and then simply logout there.

While doing so – you logoff the user and you will be able to logon again.

Monitor multiple website certificates with a single PRTG sensor

Monitor multiple website certificates with a single PRTG sensor

Due to a request on the PRTG KB of someone needing a single sensor that monitors multiple URLs for their certificate expiration I came up with the following script that is posted on this PRTG KB as well. The modified PowerShell script was provided there – it is mentioned it sourced from Stack Overflow – I found it on this link: https://stackoverflow.com/questions/28386579/modifying-ssl-cert-check-powershell-script-to-loop-through-multiple-sites

The result would look like this:

To make it more usable – you can input parameters from PRTG like this:

or this for limits – warning 60 and error 10 – you could name them but this should work as well…

And here is the modified script:

 

Microsoft RADIUS / NPS SQL logging

Microsoft RADIUS / NPS SQL logging

An issue or question I see again and again – proper RADIUS logging with Microsoft NPS / Network Policy Server.

Let’s guide you through a few steps

  1. Install a Microsoft SQL or if not available SQL Express
    1. be aware – SQL Express has very tight database size limits and no SQL Agent – this might be an issue
  2. Create a new database via SQL Management Studio in the SQL server
    1. name it e.g. RADIUSLogging
  3. run the SQL script from this Microsoft website in a new query window against this database (make sure it is not run against any other database by accident)
    1. you could add a line like USE RADIUSLogging to prevent this – in the very top…
  4. configure your RADIUS server to log to this SQL server and database
  5. make sure you have fail-over logging to a text-file – to avoid issues in case your SQL DB grew to big or was not reachable for any reason
    1. decide in the text-file configuration if you want to deny access if there is an issue or if you still want to proceed with the logon

Now you have RADIUS logging the information to a SQL database – actually a single table – and you can dig around in it. The IT-Assets database provides a front-end example for this – you don’t need to use it – but it might be of help – see here.

To interpret all those columns and values – look at the following links for additional information:

You will face the issue that the database will grow rapidly – depending on how many requests go to your RADIUS system etc… Keep an close eye on it – use a monitoring software like Paessler / PRTG to monitor the size and keep in mind that SQL Express might have size limits like 10 GB. The full version of Microsoft SQL has no such limits and further can you use SQL Agent to execute tasks. The following script can help you purging data from the RADIUS database to keep its size under control. You can use SQL Agent (not in SQL Express) to run it automatically or if you use SQL Express either run it manually or with another solution somehow automatically against the database delete older entries.

The script actually will purge data older then 14 days – you can adjust the days to your liking / needs.

Enable SMBv1 on Windows 10 per GPO

Enable SMBv1 on Windows 10 per GPO

SMBv1 is an insecure protocol that you should not use if by any means possible. Windows 10 has SMBv1 disabled by default. In order to enable it you would need to go to the Control Panel and activate the Windows Feature “SMB 1.0/CIFS File Sharing Support” and at a bare minim the “SMB 1.0/CIFS Client“. You actually might just want to do that cause you really shouldn’t add more SMBv1 servers to your network.

Before you proceed reading – if you really need to enable this protocol – please make sure your systems are all patched! Especially your target servers should be patched as well – assuming they are Windows XP / 2003 / Vista / 2008 / 7 / 2008 R2 / 8 / 8.1 / 2012 / 2012 R2 / 2016 and 10. I highly recommend to look at this Microsoft link: https://docs.microsoft.com/en-us/security-updates/securitybulletins/2017/ms17-010. Additionally do I want to mention that Windows XP and Windows 2003 can be patched as well – though they are not on the list of the previous link. Look at Microsoft KB4012598 for more information or use this download link https://www.microsoft.com/en-us/download/details.aspx?id=55245. I can not warn enough about SMBv1 – you open the doors for malware here that can bring down your network in minutes and cause huge damage!

Please note – I did not research in detail if other previous Windows versions did disabled SMBv1 already by default, this article might in any case apply to Windows 7, 8 and 8.1 as well and be applicable to Windows 2008, 2008 R2, 2012, 2012 R2 and 2016 as well as newer Windows versions to come.

Now, the issue with Windows 10 and SMBv1 disabled is that often old legacy Windows 2003 servers are around that can’t just be upgraded or replaced. In order to access any file share you would need to enable SMBv1 on the client workstations. This could sure be done by preparing your installation image etc. – but if you did not plan for this or want to have more granular control, you might consider using Group Policies / GPO to enabled this Windows Feature.

 

It is further worth noting that the easiest way to find the issue is not trying to access the UNC share via the server-name rather then directly typing in the IP address in your attempt. This way you actually get a way clearer error-message from Windows. I mention this, to show you and explain that there actually is a difference between trying to access a server-name and an IP address per UNC path – especially when it comes down to Windows 10 and the error messages you might see.

Officially enabling a Windows Feature is not supported per GPOs nor is there much information out there on how to enable SMBv1 per GPO. Having faced this challenge recently, I found a good working way that is pretty easy to implement.

  1. enable the feature on 1x Windows 10 client
    1. export / document the registry key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mrxsmb10
    2. copy the file %windir%\system32\drivers\mrxsmb10.sys
  2. create a GPO
    1. put the mrxsmb10.sys in the GPO or a central accessible file (the target computer account must be able to read the file! – I often put it in either NETLOGON or directly in the GPO / scripts folder)
    2. Computer Configuration \ Preferences \ Windows Settings \ Files
      1. create a new entry to copy the file to the target system
      2. Source file: where you centrally placed the mrxsmb10.sys
      3. Destination file: %windir%\system32\drivers\mrxsmb10.sys
    3. Computer Configuration \ Preferences \ Windows Settings \ Registry
      1. Create or import all the registry keys from HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mrxsmb10

A registry hive export would look like this:

Apply the GPO to your target systems / workstations and reboot them – after that you will be able to access the necessary shares. The downside is – you don’t really see the feature as enabled in the Windows-Features. It will work nevertheless.

 

Monitor user accounts in Active Directory with PRTG

Monitor user accounts in Active Directory with PRTG

The following script will read through your current Active Directory and filter for user accounts with the following specific conditions:

  • Lockedout users – please read below for further information about this
    • all users that are lockedout
    • must be an enabled user
    • that is not expired
  • disabled users
    • all users that have been disabled
  • expired users
    • must be an enabled user
    • the expiration date is set and past the current date
  • users with password never expires set
    • must be an enabled user

This will give you a pure counter output per channel in an for PRTG Extended script sensor XML result.

But there is a theoretical flaw in one of the methods – the locked out users. Now, user accounts get locked out in Active Directory due to too many logon attempts with an invalid password. This causes Active Directory to set the lockedout bit in the object properties. The issue here is that this bit will not be set back to 0 after the defined lockout duration (GPO) is past, the property will only be set back to 0 once the lockout duration is passed and he successfully logged on.

This means, the counter might give you more results then currently true, it might count users that have been locked out but the lockout-duration passed – but they did not yet logon successfully. This is somehow a false positive, while not totally false. In any case, you need to be aware of this.

The script could be more efficient as well in the way it filters a few things, so far I optimized it as far as I could – the LockedOut value can not be set as a -Filter, in theory it might be possible to speed it up with a -Filter to the UserAccountControl (if that is even possible – not tested) – but I am not certain this would work. If you really want to speed it up you would need to work with -LDAPFilter – but this actually needs to completely replace the internal filter capabilities of Get-ADUser – you can’t use both – it is one or the other.

This script updated with a corrected version as of February 2019 and was also posted in the PRTG knowledge base here.

Password expiration notifications for end users

Password expiration notifications for end users

Today I wanted to share a script with you that allows you to inform your users per email that their password will expire or even is expired and reminds them about your password policies like complex passwords and how to chose a password. This is a simple VBScript and can easily be adjusted. The email will be generated from a file, in this case a HTML file that you provide. You can adjust the content of this HTML file as you need it. There are sure many commercial solutions out there that can do more then this script, but if you want to save the money and are satisfied with the provided options, this sure can be a good alternative.

Let me mention one thing about passwords first – most of us live with the usual policy that passwords should be changed periodically and need to be of a certain length and complexity. We all live with the daily calls of the help-desk about forgotten passwords, not changed passwords (pretty much why I wrote the script) and so on – what changed was a new recommendation in late 2017 or early 2018 that actually is based on statistics and data and now says – yes – complex passwords and certain lengths – but do not enforce periodic changes of those passwords due to this actually resulting in to less secure passwords while users might only change a number or even write those passwords more likely down and therefor compromising the whole attempt to secure the system.

Anyways – the next few lines will explain the parameters you can adjust in the top section of the VBS script – further below I will post the script and an example HTML file so you can start right away.

The options are between the lines 7 and 61 – don’t be scared – most of them are pretty simple to understand and are actually explained in the script itself. You should not need to modify anything outside those two lines.

About the parameter naming convention and possible values:

  • starting with str as strings – those expect text-markers and alphanumeric values “text”
  • starting with int as integer values – those are direct numeric values – e.g. 123
  • starting with bol are boolean values – those can be either TRUE or FALSE – meaning on or off

Here are the options you can set:

  • strSMTPServer: SMTP mail server DNS name or IP address
  • intSMTPServerPort: SMTP mail server port – normally 25
  • strFrom: SMTP mail from address
  • strToAdmin: SMTP mail to address for administrator emails
  • strAdminMailSubject: subject for mail to administrators
  • strUserMailSubjectExpired: subject for mails to user when password is expired
  • strUserMailSubjectWillExpire: subject for mail to user when password will expire – the exact word REPLACEWITHDAYS will be replaced by the days left value so mention it in the subject line if you want to see the value there
  • strBodyURL: URL or full file-path (HTML file path e.g. file://) to import for body, the entire content of this URL/FILE will be imported to the body of the email and should explain ways how to change the password
  • strAttachment: full file-path to an attachment for the email to the users / leave empty if no attachment
  • strLDAPSortColumn: per default: pwdLastSet / sort column for LDAP query
  • intStartWithPWexpiresInDays: If the passwords expires in days N or less, the script will inform the user – keep in mind – if you run the script daily, those users will get an email every day once their password will expire in less then the indicated days. 5 is sure a good start.
  • bolIgnoreDisabledAccounts: Disabled accounts should always be ignored
  • bolInformAdminAboutPWexpires: this will inform the admin about expiring passwords
  • bolInformAdminAboutPWisExpired: this will inform the admin about accounts with expired passwords
  • bolInformAdminAboutPWneverExpires: this will inform the admin about accounts with password set to never expire
  • bolInformAdminAboutUserCantChangePW: this will inform the admin about users who are not allowed to change their password
  • bolInformAdminAboutAccountDisabled: this will inform the admin about disabled accounts found – this would have been done in ADS by an administrator
  • bolInformAdminAboutExpiredUserAccount: this will inform the admin if the user account has an expiration date and the account is expired
  • bolInformAdminAboutAccountWithoutEMail: this will inform the admin about accounts without a set email address
  • bolInformAdminAboutStillGoodPasswords: this will inform the admin about users/passwords that are still valid
  • bolInformAdminAboutIgnoredUsersExcludedByGroup: this will inform the admin about users that have been ignored by the strGroupsExclude filter
  • Please Note: the status account locked will not be checked, this should be corrected automatically by the default security GPO instead (will be in most cases by default)
  • strSearchOUs: Filter Priority 1 – only users in those OU paths will be processed. Use LDAP DN like: “OU=Folder,OU=Folder,DC=Domain,DC=local”, you do not need to include the DC=Domain,DC=local – the script will add this information if necessary. Use | (pipe) if you want to add more then one LDAP DN path. Leave empty (“”) to disable this filter
  • strGroupsExclude : Filter Priority 2 – if the user object is still not excluded, this group exclude filter will be applied. If the user is member of one of those groups (if multiple groups are defined), he will be ignored. Use | (pipe) if you want to add more then one GroupName. Leave empty (“”) to disable this filter. Example: “Group Number1|GroupNumber2”
  • strGroupsInclude: Filter Priority 3 – if the user object is still not excluded, this group Include filter will be applied. The user has to be a member of one of those groups (if multiple groups are defined). Use | (pipe) if you want to add more then one GroupName. Leave empty (“”) to disable this filter. Example: “Group Number1|GroupNumber2”
  • bolDebug: set TRUE for script-output, highly recommended to execute the Script in CMD with CSCRIPT <ScriptName> so you see it in a command window instead of dialog boxes.
  • bolAttachDebugToAdminMail: the debug output will be attached to the admin-mail (independent from bolDebug)
  • bolTestDebugOutputToConsoleOnly: this will disable the mail.send – only output to the CMD will be generated, please enable bolDebug
  • bolRedirectMailToAdmin: this will redirect all mails to the admin, instead of sending them to the user – the subject line will include the user-mail address in this case – this allows you to do a real test and actually see what would be send out to whom – without actually sending the emails to the end user
  • bolAdminMailOnly: this will send the admin-mail only, no user mail will be generated

As always – feel free to reach out to me if you have any questions or comments.

Join systems to a domain and create KeePass server entries for local admin’s

Join systems to a domain and create KeePass server entries for local admin’s

Please note – this script was updated – you find the updated post here.

One of the challenges in most daily IT operations is onboarding of workstations and servers (respective domain join). Over the years I came across and tried many ways to accomplish this. Today I wanted to share a script and solution others might find helpful, but first lets get down to some theory and background.

The goals and challenges:

  • simple domain join after a system was imaged
    • this is in theory possible in a fully automated process via various imaging solutions – I found that WDS (Microsoft Windows Deployment Services are in most cases the easiest way to accomplish this while having the possibility to use this in consulting for various clients, in enterprise for various departments etc. Since Windows 10 came in to the equation some of the automation with WDS became more challenging – so keeping it simple with some additional manual labor is often the easiest way to accomplish this – to simplify the process a PowerShell script became a perfect solution).
  • systems should have a local admin account (not administrator / SID 500 / who should remain disabled) with an individual password
    • typing this manual you always risk that the password is misspelled either in your password database or on the actual operating system
    • if you think it is a good idea to have the same password on all your clients I actually suggest you do some security related research!

The PowerShell script below will do the following for you:

  1. Ask for the name of the system (this will change the hostname/computername)
  2. Ask for credentials for KeePassPleasant Password Server
  3. Ask for credentials to join the system to the domain
  4. Create a local admin user account on the system
  5. Generate a password for this account
  6. Check if there is an existing KeePassPleasant Password Server entry for this system
  7. If not – it will proceed and create a entry with the machine name, username, password and various additional information like
    1. manufacturer
    2. model
    3. serial number / service tag
    4. UEFI BIOS Windows license key
    5. MAC addresses of all network cards Windows knows about
  8. And finally it will join the domain and put the system right away in to the defined OU

The whole script is only an example – you don’t have to use KeePassPleasant Password Server nor is the script perfect for any situation – you can take it and modify it as you need it – point it to various IT Asset databases or let you chose from predefined OUs etc. – adjust it as you needed – in general it is a very useful baseline and I wanted to share it.

One of the challenges is to execute the script as administrator (elevated rights) and as well bypass the script execution restrictions without compromising them in a default image, like disabling this important security feature on the image itself. To accomplish this, a simple CMD-Script actually will execute the PowerShell script. CMD-Script can right-clicked and executed as administrator and gain elevated rights. This is as of today not possible by default with PowerShell scripts (.ps1).

Create the following two files “Execute-DomainJoin.cmd” and “Execute-DomainJoin.ps1” and save them in the same directory or e.g. a portable flash drive. Adjust the PowerShell script so it connects to your domain and local systems.

Please note – this script was updated – you find the updated post here.

Explaining, adjusting and guiding your through the PowerShell script

It is important that you understand the script so you can make adjustments to it. I will try to explain everything that is important and reference some line-numbers while doing so.

  1. Lines 1-30 are just a general introduction and show some generic information
  2. Lines 31-76 hold some functions to generate a password, to bypass some certificate issues etc
    1. Lines 35-38 are worth taking a look at, here are all the characters of the four categories that will be used to generate a password. Excluded are already usually hard to read characters in some fonts and other characters that might cause issues – of course, adjust especially line 38 to your preferences and add more symbols or remove what you don’t want to use
  3. Lines 77-89 are just informational
  4. Lines 90-96 expect some user-input
    1. new computername
    2. get credentials for the domain join (admin)
      1. the script will not validate the credentials, in theory this could be done but I never found it that important
    3. get credentials to read/write on the password database server (often not the actual admin-credentials, therefor I separated those two)
      1. the script will not validate the credentials, in theory this could be done but I never found it that important
    4. the local admin username that will be created
      1. $localAdminUser = $(“$ComputerName” + “_Admin”)
      2. the above line will create a hostname_admin account – you can adjust this to your preferences
    5. 94-95 will generate a password and encrypt it so it can be used to create the local account
  5. Lines 97-103 are just informational
  6. Lines 104-216 – this is actually the whole password server communication and entry check and generation
    1. 104-115 those lines gather various information from your current system like serial number, UEFI Windows keys, etc. – you can keep em as is
    2. 116 – please enter the URL to your password server here 
    3. 117 – here your need to enter the folder where the generated credentials are going to be put in on your password server
    4. 118 – this is the subject of the entry that will be generated – adjust this to your preferences
    5. 119-120 – those are username/password for the entry – you should leave this as is
    6. 121-134 – those lines are the details in your password server entry – adjust them to your likes
    7. 135-165 – this actually will execute the following on the REST API on your password server
      1. connect to it
      2. check if a entry with the same username already exists
    8. 166-189 – this will raise an alert that this user already exists on your password server – 189 will actually exit the whole script
    9. 190-216 – this block will write to the password server – cause it did not find an entry with the new username
  7. Lines 217-241 this shows the new created username and password – it actually suggests you compare the entries on your password server to the information shown to make sure everything is correct
  8. Lines 242-251 will create the new local admin account on the system and set the password
  9. Lines 252-267 are informational
  10. Line 268 will execute the actual domain join
    1. please adjust the -Domain and the -OUPath parameter to your specific needs
    2. note that the command will automatically restart the system
  11. Lines 269-282 Those lines are informational – actually – if anything would go wrong those lines would be shown and help to take further steps after the failed domain join – in most cases those suggestions will help – in the end the error output shown by the command for the domain join (line 268) would indicate what went wrong. The restart of the system actually would bypass this message in the end (more or less)

If you have any questions, feel free to reach out to me. The script could be cleaned up more – but I wanted to provide a working version of it – so I just did a quick clean up or some special stuff and posted it here. Personally I like things a bit more structured, but as said – this is just a general example.

Please note – this script was updated – you find the updated post here.

This script is also mentioned on the API Examples page on the Pleasant Solutions web site here.