Friday, October 14, 2011

RegistryProfileCleanup - cleartext

Several people have asked me for the VBS code to my "Efficient Registry Cleanup" script, since the link went down. I'm not using any time on this blog these days, so this is just a quick & dirty fix:

Also the "Get User Profile Dirs From Registry" script is here:


P.S. The article is still here:

InstallGPPCSE - cleartext

Several people have asked me for the VBS code to my GPP CSE Install script since the link went down. I'm not using any time on this blog these days, so this is just a quick & dirty fix:


Friday, June 24, 2011

FlexCommand - cleartext

Several people have asked me for the HTA code to my FlexCommand tool since the link went down. I'm not using any time on this blog these days, so this is just a quick & dirty fix:


Sunday, May 24, 2009

Unique passwords on local user accounts using VBS and Group Policy

The purpose of the script (SetLocalPassword.v2.txt - just rename to "SetLocalPassword.vbs") is, to ensure assignment of unique and complex password to a specific local user account (typically the local administrator account) on a Windows client in an Active Directory (AD) domain environment.

The script can be used, if you (for one reason or another) want a specified local user account (e.g. administrator) to be active, but you still want to ensure, that the password used is unique for each computer, that the password is changed regularly (a given period of time) and that you are able to logon using the password at any time. Usually I would recommend customers to just deactivate the local administrator account, or set the password using Group Policy Preferences (preferably different passwords on different security areas), but if these solutions aren’t usable in the environment, “ChangeLocalPassword.vbs” could be the right solution.

The intention is to execute the script as a "Startup Script” within a Group Policy Object (GPO), which is aimed at the relevant computer accounts in AD (as you probably know GPO’s can be filtered by AD security groups, WMI filters, Organizational Units (OU), domain and/or site). This way we ensure that the script is executed in ”SYSTEM" context, in which we can pretty much do anything on the local computer(s). Furthermore, SYSTEM can access network resources on behalf of the computer, as long as the resource in question (a file share in this case) allows “Domain Computers”, the specific AD computer account og “Authenticated Users” to gain access.

It is crucial that the group ”Authenticated Users” is NOT given access to the network share – in that case all users within the domain will be able to read which passwords are used on all computers hit by the GPO. Share permissions (could be a hidden share$) can of course be set to Everyone Full Control, but NTFS must be set to allow only members of the group "Domain Computers" to read and write - domain administrators, and other relevant groups (e.g. helpdesk, supporters, backup account etc.) should also have read access. If you have a Distributed File System (DFS) up and running it could be used as the network share.

This illustrates the scripts cycle:

1. The SYSTEM account is used by the computer during the boot process
2. DNS and AD is contacted, and Group Policies are processed (machine policies)
3. The GPO with the Startup Script is loaded
4. The VBS script is executed (also in SYSTEM context)
5. All activity is logged to a local log file (strLocalLog)
6. Some preliminary checks are performed, this includes last modification of strLocalStamp and network access (strNetShare)
7. A password (strNewPassword) is generated from 4 different criteras (intPasswordLength, intWantNumber, intWantLcase and intWantUcase)
8. The username and password (clear text) is logged in a central log file (strnetFile)
9. The chosen local user account (strLocalUser) is assigned the newly generated password (only if 8 was completed without any errors)
10. A local timestamp file is created or modified if 9 was successfully completed

Some important notes...

First and foremost one must ensure, that the script file the GPO is pointing to cannot be modified by others than the relevant administrators. If a user gets write access to that file, he or she can do anything (locally) on all machines executing the code. This is of course true for any GPO Startup Script used.

Another important thing to note is, that if your users have local admin rights (I hope not), they will be able to “hack” the solution in a couple of ways. First of all they will of course be able to reset passwords for all local user accounts, but if they are a bit clever, they will also be able to take over the SYSTEM account (hint: AT command or PSEXEC) and access the network share we are using – and thus read or modify the log files with all the clear text passwords. But who in the world would allow users to be local administrators in the fist place, right?

A Startup Script will time out if the script takes too long to execute, but we should not have such a problem with this script (normally executed in less than a second). Startup Scripts react differently depending on whether the “Always wait for the network at computer startup and logo” setting is set or not - the script should work in both cases though.

Let’s take a look at the customizable variables.

intDays = 60
- default: 60 days between password change

strNetShare = "\\SERVER\SHARE\"
- define as a share with the correct NTFS permissions set
- is could be a hidden share, perhaps on a DFS
- remember a trailing backslash (\) or the script will fail!

strLocalLog = "C:\admpwd.log"
- placement of the local log file of all activity (except for the password itself)

strLocalStamp = "C:\admpwd.stp"
- placement of the file used as a timestamp

strLocalUser = "test-user"
- name the user account to control (e.g. "administrator")

intPasswordLength = 12
- the number of characters the password should have (exactly)
- must be at least the same as the domains minimum password length

intWantNumbers = 1
- set whether or not the password should contain numbers (complexity requirement)

intWantLcase = 1
- set whether or not the password should contain lowercase letters (complexity requirement)

intWantUcase = 1
- set whether or not the password should contain UPPERCASE letters (complexity requirement)

An example of the strLocalLog (default "c:\admpwd.log") local log file:

2009-05-22 13:20:26 [STARTED]
2009-05-22 13:20:26 [VARIABLES - A]
2009-05-22 13:20:26 - intDays : 1
2009-05-22 13:20:26 - strNetShare : '\\SERVER\SHARE\'
2009-05-22 13:20:26 - strLocalLog : 'C:\admpwd.log'
2009-05-22 13:20:26 - strLocalStamp : 'C:\admpwd.stp'
2009-05-22 13:20:26 - strLocalUser : 'test-user'
2009-05-22 13:20:26 - strComputer : 'COMPUTER1'
2009-05-22 13:20:26 - strNetFile : '\\SERVER\SHARE\COMPUTER1.log'
2009-05-22 13:20:26 STATUS - No local stamp file, probably first run
2009-05-22 13:20:26 SUCCESS - ALIVE:\\SERVER\SHARE\
2009-05-22 13:20:26 [VARIABLES - B]
2009-05-22 13:20:26 - intPasswordLength: 12
2009-05-22 13:20:26 - intWantNumbers : 1
2009-05-22 13:20:26 - intWantLcase : 1
2009-05-22 13:20:26 - intWantUcase : 1
2009-05-22 13:20:26 SUCCESS - PWD SET for: 'test-user'
2009-05-22 13:20:26 SUCCESS - PWD written to: '\\SERVER\SHARE\COMPUTER1.log'
2009-05-22 13:20:26 SUCCESS - TIME written to: 'C:\admpwd.stp'
2009-05-22 13:20:26 [COMPLETED]

2009-05-22 13:27:45 [STARTED]
2009-05-22 13:27:45 [VARIABLES - A]
2009-05-22 13:27:45 - intDays : 1
2009-05-22 13:27:45 - strNetShare : '\\SERVER\SHARE\'
2009-05-22 13:27:45 - strLocalLog : 'C:\admpwd.log'
2009-05-22 13:27:45 - strLocalStamp : 'C:\admpwd.stp'
2009-05-22 13:27:45 - strLocalUser : 'test-user'
2009-05-22 13:27:45 - strComputer : 'COMPUTER1'
2009-05-22 13:27:45 - strNetFile : '\\SERVER\SHARE\COMPUTER1.log'
2009-05-22 13:27:45 STATUS - STAMP last modified: 22-05-2009 13:20:26
2009-05-22 13:27:45 STATUS - STAMP younger than: 1 days!
2009-05-22 13:27:45 [COMPLETED]

An example of the strNetFile (named [computername].log) network log file:

2009-05-20 13:20:26 test-user : 'W57Ja6c5Xcus'
2009-05-22 08:10:39 test-user : 'sdEc7s9Gbba8'

Final note:

The code could most definitely be more optimized (and prettier), but it works like a charm (and pretty fast too) on Windows 2000, Windows XP, Windows Vista, Windows Server 2003, Windows Server 2008 and Windows 7.

I hope it will turn out to be useful to someone out there - enjoy!


Friday, January 09, 2009

Get email address of all users from all mails in an Outlook Folder

Ever had the need to extract all email adresses from a folder in Outlook?

Let's say you want to make a reply to a lot of people who are not in your addressbook (contacts), but who have sent you an email which you have archived in a specific folder (or from your Sent items).

I archive my emails all the time using one folder pr. "case", "customer" etc. - and sometimes it's ery useful to be able to write to everyone who had to do with the specific case. This is when it get's a bit frustrating - you have to find a way to get all the email-adresses, and only once!

This is how to do it the easy way:
1. In Outlook press ALT+F11 (opens Microsoft Visual Basic console)
2. Open "ThisOutlookSession" from the Project tree (left menubar)
3. Paste the code below into the project (right window)
4. Press F5 to Run the code (execute)
5. Select the folder you want to use and hit OK (might take some time to complete)
6. Press ALT+G and then copy the email-addresses from the "immediate" window (debug window)

Oh, and remember to use the BCC field if they shouldn't see eachothers email addresses (in the case you want to send an email to all of them).

Sub GetEmailAddressesInFolder()
Dim objFolder As MAPIFolder

Dim strEmail As String
Dim strEmails As String
Dim objItem As Object

Set objFolder = Application.GetNamespace("Mapi").PickFolder

For Each objItem In objFolder.Items
If objItem.Class = olMail Then
strEmail = objItem.SenderEmailAddress
If InStr(strEmails, strEmail) = 0 Then strEmails = strEmails + strEmail + ";"
End If
Debug.Print strEmails
End Sub

The above code is tested on Microsoft Outlook 2007, but should work on older Office systems too.

Original source here - I just had to modify the code a bit.

Bye for now!

Wednesday, November 05, 2008

Software Restriction in Windows 7

These are some quick notes from a session on AppLocker by Paul A. Cooke, Tech-Ed EMEA 2008:

As you may have seen, I’ve written a few articles on Software Restriction Policy (SRP) under Windows XP and Windows Vista for (see below). I’m very happy to tell you, that Microsoft now improved this functionality and renamed it into: AppLocker!

Unfortunately I cannot bring you any screenshots (because of NDA), but I can tell you a few things about the basic functionality. With AppLocker you can more easily eliminate unwanted and unknown applications in your Windows (7) environment. You can enforce application standardization – both from a security (malware), and from a management point of view (licensing & user control).

What most organizations try to do these days, it to limit users to be standard users (non-administrators) on their local machines – however this is actually not enough to feel secure as an IT administrator. Running as standard user is not the solution to all of our problems. Many applications can do bad stuff, even within user context – like stealing data, deleting data, manipulating data, encrypting data, creating bot-nets, send spam, social engineering etc. etc. This is true for applications that install in user context (like Google Chrome), or regular executables that don’t actually install – they just run!

If you want to control applications like that, what can run and what cannot – then you need another approach. AppLocker comes to the rescue!

AppLocker has been build around digital signatures – signing of software executables and DLLs. This was also an option in SRP under Windows XP, were we had path, filename, HASH & certificate rule, but it was pretty hard to manage and enforce back then. With Windows 7, a new GUI has been added to the group policy editor to support easy creation of software rules. We have 3 types of rules:
- Allow rules: same as Whitelisting (‘known good’ software)
- Deny rules: same as Blacklisting (‘known bad’ software)
- Exceptions: exclusion from allow or deny rules

Allow rules are of course the recommended approach – the “default deny all applications” rule (Whitelisting), but with specific applications the network administrators wants to allow users to run. As an administrator, you get granular control of specific applications, enforcing who can run and/or install them (if they have the appropriate rights and permissions).

The administration is done by group policy under Computer Configuration > Application Control Policies, but strangely enough you have to put in affected users and groups (still unclear whether or not the SYSTEM account is still excluded from SRP checks). So this is actually Computer policies that are able to hit users, like loopback or group policy preferences.

You can create multiple rule sets and take advantage of specific attributes, like app version (equal/above/below X.0.0.0), filename (executable name), product publisher (the valid root certificate used to sign), product suite (like “Microsoft Office 2007”) – and wildcards seems to be supported still.

You can control executables, installers (MSI), scripts, and DLLs, using certificates (publisher), HASH or path rules. The disadvantage of using HASH rules is, that the HASH will change if the application is updated, certificate/publisher rules are much more flexible because the signature is still going to be there (unless the developers totally mess up). So always try to go for publisher rules, certificates are here to stay :)

Can be run in 3 modes: Enforce policy, Enforce Policy using Group Policy Inheritance  and Audit Only mode! The latter is pretty cool, as you can configure a Software Restriction Policy, and test it out before you go “live”.

AppLocker supports import and export of rules, which can be very useful, but one of the best new features is, that there’s no need to create all the rules manually – you have the option to “automatically generate rule”, this feature will analyze a “reference machine” (not sure if this has to be the local machine yet) and files in a given folder on that machine (not sure if this can be a share yet). You can compare this to a “snapshot” feature, take all files in this folder (and subfolders), and make an allow rule from that (certificate based preferably).

The new rule creation tools and wizards seem pretty straight forward – but you really need to think about the SRP design before you go for it, and test intensively, or else you’ll end up in serious trouble ;-)


I just can’t wait to test this deeply and bring you more information!


Previous article series on SRP:
Default Deny All Applications (Part 1)
Default Deny All Applications (Part 2)

Microsoft AppLocker description:


User Account Control in Windows 7

These are some quick notes from a session on UAC by Paul A. Cooke, Tech-Ed EMEA 2008:

Microsoft Windows 7 will reduce the number of OS applications and tasks, that require elevation – this has been done by re-factoring apps and tasks into elevated and non-elevated pieces.

UAC v2 will provide a more flexible prompt behavior for administrators, also administrators will see less UAC elevation prompts.

Users can do even more as standard user (eg. parts of Bitlocker, Windows Update etc.), they will also be able to ‘read’ system settings without needing to elevate.

Windows 7 will be better spotting human vs. application changes, this way “human administrator” changes will be allowed without too many prompts.

UAC can now easily be graduated into 4 levels (from the strict Vista default to totally off) - everything can of course be handled using group policy.


To me this is all pretty cool – but to be honest, I’m one of those weird guys, who don’t care about Vista UAC prompts… I just press ALT+C… How hard can it be? ;-)


Monday, October 20, 2008

I just love sharing!

Just found this - using Google Alerts of course :)

I made little modifications on this script created by Jakob Heidelberg to search for printers manually created on user profiles. This is very usefull when you wanna ensure that eveybody has only auto created printers, from Citrix or ThinPrint.

This script load ntuser.dat on each profile, check some registry keys, write a log and unload ntuser.dat. Some users can have problems to load their profiles if you use this script on the same time that they try logon.

I just love sharing!

Sunday, October 12, 2008

Why does standby overrule shutdown?

Well, I’m a Microsoft kinda guy – but I do have a problem with one “feature” which has been part of the Windows OS for some time…

Normally I change the default behavior under Power Setting, so that Windows does NOT start a STANDBY process when I close the lid of my laptops – but I haven’t done it on all of my machines, and under every user profile I have (and customers have the same issue).

So, what happens is, that you are done for the day, and then you start a SHUTDOWN process like normally, and then you close the laptops lid – a STANDBY process then starts – Doh!

That means, the SHUTDOWN process is put into STANDBY mode, and the next time you boot your laptop, the machine state resumes, just to finalize the SHUTDOWN process… And then you have to boot you machine to get started – hmmm, I definitely don’t like it!

So what should happen? Well, when a SHUTDOWN process had started, a STANDBY process should NOT be able to “take over” – just let me close the laptop lid and continue the already started SHUTDOWN process, thanx :)

OK, I admit that it’s only a problem when I haven’t changed the default Power Settings, but I can’t be the only human being in this world with that particular problem!?!? Why would you EVER want a SHUTDOWN process to be put into STANDBY mode?


BTW – I have seen, that Mac and Ubuntu people have the same issue on some version – don’t know if it has been fixed on those OS – I have the problem on all the different Windows systems I run on laptops.