Search This Blog

Thursday, June 20, 2013

Should I use .local as part of the domain name? No, here are some info about it

Hi,

I've talked to many customers about using .local in the domain name (example: mydomain.local). I've always stated that they should not and some of the reasons are:

----snip----
From: http://en.wikipedia.org/wiki/.local

Multicast DNS standard
Internet Engineering Task Force (IETF) standards-track RFC 6762, which has been approved and was officially published on February 20, 2013, essentially reserves the use of .local as a pseudo-TLD for link-local hostnames that can be resolved via the Multicast DNS name resolution protocol. Page 5 of that publication states:

...this document allows any computer user to elect to give their computers link-local Multicast DNS host names of the form: "single-dns-label.local.". For example, a laptop computer may answer to the name "MyComputer.local."...

This document specifies that the DNS top-level domain ".local." is a special domain with special semantics, namely that any fully qualified name ending in ".local." is link-local, and names within this domain are meaningful only on the link where they originate. This is analogous to IPv4 addresses in the 169.254/16 prefix or IPv6 addresses in the FE80::/10 prefix, which are link-local and meaningful only on the link where they originate.

Any DNS query for a name ending with ".local." MUST be sent to the mDNS IPv4 link-local multicast address 224.0.0.251 (or its IPv6 equivalent FF02::FB)  

...Implementers MAY choose to look up such names concurrently via other mechanisms (e.g., Unicast DNS) and coalesce the results in some fashion. Implementers choosing to do this should be aware of the potential for user confusion when a given name can produce different results depending on external network conditions (such as, but not limited to, which name lookup mechanism responds faster).

Name resolution issues may arise if multicast DNS software is used in conjunction with a network that implements the local top-level DNS domain.

MS Recommendations
The connection of Macintosh and Linux computers and/or zeroconf peripherals to Windows networks can be problematic if those networks include name servers that use .local as a search domain for internal devices.

At one time, Microsoft at least suggested the use of .local as a pseudo-TLD for small private networks with internal DNS servers, via documents that (as of this writing) are still accessible. For example, support article 296250 included the following option:

Make the name a private domain name that is used for name resolution on the internal Small Business Server network. This name is usually configured with the first-level domain of .local. At the present time, the .local domain name is not registered on the Internet.

However, more recent articles have cautioned or advised against such use of the .local TLD.
Support article 300684 listed contoso.local as an example of a "best-practice Active Directory domain name", but then added:

We recommend that you register DNS names for the top-most internal and external DNS namespaces with an Internet registrar. which would of course preclude using that or any other domain ending with .local.

Technet article 708159 suggested .local for the exact opposite reason:
Using the .local label for the full DNS name for the internal domain is a more secure configuration because the .local label is not registered for use on the Internet. This separates your internal domain from your public Internet domain name.

but later recommended against it:
If you have Macintosh client computers that are running the Macintosh OS X version 10.2 operating system or later, ... it is recommended that you do not use the .local label for the full DNS name of your internal domain. If you have Macintosh client computers that are running the Macintosh OS X version 10.3 operating system or later, ... it is recommended that you do not use the .local label for the full DNS name of your internal domain. If you must use the .local label, then you must also configure settings on the Macintosh computers so they can discover other computers on the network. For more information about how to configure client computers running Macintosh OS X version 10.3 or later, see "Connecting Macintosh Computers to a Windows Small Business Server 2003 Network" on the Microsoft Web site.

Technet article 726016[5] cautioned against using .local:
...we do not recommend using unregistered suffixes, such as .local.

Global .local DNS queries
.local is an officially reserved Special-Use Domain Name and such host names will never be resolvable by the global Domain Name System

 References
1.Cheshire, Stuart, and Krochmal, Marc. "RFC 6762: Multicast DNS". Internet Engineering Task Force.
2."Domain Name System name recommendations for Small Business Server 2000 and Windows Small Business Server 2003". support.microsoft.com.
3."Information about configuring Active Directory domains by using single-label DNS names". support.microsoft.com.
4."Internal Domain Information (OEM)". technet.microsoft.com.
5."Selecting the Forest Root Domain". technet.microsoft.com.
6."Special-Use Domain Names".
7.George Kirikos. "Most Popular Invalid TLDs Should Be Reserved". Circle ID. Archived from the original on 21 June 2009. Retrieved 2013-04-12.
8."Most Popular TLDs Queried". root-servers.org. Archived from the original on 2009-09-16.
----snip----

More info:

Active Directory Domain Naming Considerations:
http://social.technet.microsoft.com/wiki/contents/articles/17974.active-directory-domain-naming-considerations.aspx

I will post more about this when time permits.

Best regards,
/Jimmy

Wednesday, June 12, 2013

Should I use Rendom.exe?

Well, it all comes down to your environment and how it can handle down-time. Personally I would migrate if possible due to the complexity of the domain rename process.
What you need to understand is that the domain rename process is complex and in some ways "uncontrolled". Meaning that if you start it, it will try to finish or fail.

Things to understand:
- Headless Management: Rendom will not use AD Repl, each DC will be contacted individually.
- Forest will be "offline" during the process: The time is proportional to the number of DCs.
- DC is either successful or must be removed from the forest.
- Member computers must be rebooted twise after all DCs are updated, note that legacy OS needs to unjoin/join the domain.
- DNS host names are not automatically changed during rendom: Primary DNS suffix of the DC will not mathc the new domain DNS name. Requires additional steps after rendom.
- DNS suffix on member computers will not match for a period of time: Time it takes is proportional to the number of machines in the domain and if it is auto updated or not.
- Runs from a separate computer
- CLI interface
- Each DC is changed independently
- Step-by-step, steps must succeed on every DC or it stops
- Steps are idempotent

3 DC states:
- Initial
- Prepared
- Final (success or fail)

Note that Prepared to Final can only be accomplished if every DC in the forest has reached the required state!

Overview of the steps:
- Manually specify the new forest structure
- Generate instructions encoded as script
- Transfer the script to each DC
- Verify the script on every DC to see if it is ready to execute the instructions
- Execute instructions on each DC (forest offline during this step)
- Fix-up Policy metadata
- Clean-up metadata written to the directory

Remember that this is just a basic overview of how it works, you must test, test again and test again in a lab before trying it in production!

The LastLogonTimeStamp Attribute – What it was designed for and how it works

I came across an excellent explanation of the LastLogonTimeStamp attribute and how it actually works:
http://blogs.technet.com/b/askds/archive/2009/04/15/the-lastlogontimestamp-attribute-what-it-was-designed-for-and-how-it-works.aspx

If you ever had a question about it, I bet you'll find the answer there.

Monday, June 10, 2013

NON-LVR groupmembers - how to find them - Step 4.

Step 3 in my blog (http://www.jimmytheswede.blogspot.se/2013/06/non-lvr-groupmembers-how-to-find-them.html) will create a separate file for each group (DN is the filename of the group). Within those files you need to search for the string LEGACY, so what I did in step 4 was to search the files for the string LEGACY and then copy the files into a separate folder.

Note that my folder containing the files is "c:\temp\searchFiles" and I copied the files that contained the string "LEGACY" to the folder "c:\temp\searchResult".

In PowerShell:
get-childitem c:\temp\searchFiles | select-string LEGACY -List |%{copy-item -path $_.path -destination 'c:\temp\searchResult'}

Now I have all files (named as the group's DN) in a separate folder that contains LEGACY members, I then create a list of the filenames as input when I change them (http://www.jimmytheswede.blogspot.se/2013/06/non-lvr-groupmembers-how-to-change-them.html).

TechEd North America Sessions


The session recordings for TechEd  2013 are now available - http://channel9.msdn.com/Events/TechEd/NorthAmerica/2013#fbid=S8kTtlJUJv2

Friday, June 07, 2013

NON-LVR groupmembers - how to change them

After I had removed the groups I didn't want to refresh the group membership in, I ended up with a textfile called refresh.txt as input file.

I ended up using this command in a command prompt to re-add the users in the groups from this file.

for /F "delims=" %f in (refresh.txt) do dsget group %f /members | dsmod group %f /chmbr

Things you must take into consideration is that if you do this on many groups with many members, it will start a lot of replication. So, you might want to split the list into multiple smaller lists to not affect the network too much.

Wednesday, June 05, 2013

NON-LVR groupmembers - how to find them

Today I was trying to find out which group members that still was LEGACY, meaning not using LVR. I was definately not going to manually look at the groups metadata since it was about 7000+ groups. So this is how I did it form the command prompt:

[the domain name is: demo.net and DC name is DC1 in this example, you need to replace that with your domain and DC]

1. Create a list of all groups in the domain:
Dsquery group dc=demo,dc=net /limit 0 > allGroups.txt

2. Remove all built-in groups and groups that are created by default during a fresh installation since I didn't want to "touch" them.

3. Get objMeta of all groups in the text file:
For /f “delims=” %f in (groups.txt) do repadmin /showobjmeta DC1 %f > metadata\%f

(metadata is the folder where I saved the output files to)

4. Now the only thing left is to search the files created in the metadata folder for LEGACY. And you will have a list of which groups contains non-LVR memberships.

When I have my complete list I will then remove/add the members to be able to utilize LVR. I haven't decided how I will do that yet, but most likely dsget group | dsmod group but I will post that after I've done it.

Evaluate group membership - Address Token Limitations

You can use this to evaluate issues with token sizes, it is especially good in environments that contain complex group structures.

In the below example, my domain is vfroot.prv and my DC name is SDF. In the below example I evaluated a group, but you can evaluate users as well.

To do this you will use the Ntdsutil command:
ntdsutil
ntdsutil: group membership evaluation
group membership evaluation: set account dc SDF
group membership evaluation: set global catalog SDF
group membership evaluation: set resource dc SDF
group membership evaluation: run vfroot.prv grouptest

This will give you output to a file called tab-separated-value (.tsv) file,  that contains the following information:

-SID in Token: Security Identifier that is part of the token.
-SID Type: The type of SID that is being added. The SID can be either the Primary SID or a SID from the sIDHistory attribute.
-SID History Count: The number of SIDs in the sIDHistory attribute for the principal represented by this SID. For a row represented by a sIDHistory SID, the value is zero.
-Distinguished Name: The Distinguished Name (DN) of the entry.
-SamAccountName: The samAccountName attribute for the SID.
-DC Queried: The domain controller (DC) that provided this SID for addition to the list of tokens.
-Group Owner: The samAccountName of the owner of the group. If the SID pertains to an object other than a group, this field contains "N/A."
-Group Owner SID: The SID of the group's owner. If the SID pertains to an object other than a group, this field contains "N/A."
-WhenCreated (UTC): The date and time when the group was created. If the SID pertains to an object other than a group, this field contains "N/A."
-WhenChanged (UTC): The last date and time when any attribute of the group was changed.
-Member WhenChanged (UTC): The last date and time when the membership attribute of the group was changed.
-GroupType WhenChanged (UTC): The last date and time when the GroupType attribute of the group was changed.
-One Level MemberOf Count: The number of groups which this entry is directly a member of.
-Total MemberOf Count: The number of groups which this entry is both directly a member of and recursively a member of.
-Group Type: The type of group that this entry represents. Some examples are: User, Domain Local Security Group, and Well Known Computers.
-Depth From User: The number of transitive links between the group in question and the user. If the user Joe was a member of Group1 which is a member of Group2 which is a member of Group3, then the depth from user Joe to Group3 would be 3. If there is more than one path from the user to Group3 then the shortest path is chosen.
-Closest Parent OU: The closest organizational unit that the entry is a member of.

For more information, please see: http://www.microsoft.com/en-us/download/details.aspx?id=13749

Tuesday, October 02, 2012

MVP 2012 - Directory Services

I received this in my mail yesterday:

___________
Dear Jimmy Andersson,

Congratulations! We are pleased to present you with the 2012 Microsoft® MVP Award! This award is given to exceptional technical community leaders who actively share their high quality, real world expertise with others. We appreciate your outstanding contributions in Directory Services technical communities during the past year.

___________

This is the 14th year in a row I got honored with this award, and I'm proud of it!

Monday, March 05, 2012

Microsoft Server and Cloud Platform Blog

The Microsoft Server and Cloud Platform Blog can be found here.

More Win8 info

Bill Laing, Corporate Vice President Server & Cloud, posted some good information about Win8 that can be found here.

Thursday, March 01, 2012

Windows 8 Consumer Preview

The Consumer Preview of Windows 8 is released and can be downloaded from MSDN. If you don't have MSDN go to this link.

Consumer Preview FAQ.

--snip--
Note before you download: Windows 8 Consumer Preview is prerelease software that may be substantially modified before it’s commercially released. Microsoft makes no warranties, express or implied, with respect to the information provided here. Some product features and functionality may require additional hardware or software. If you decide to go back to your previous operating system, you'll need to reinstall it from the recovery or installation media that came with your PC
--snip--

New Group Policy Settings in Windows 8 Consumer Preview

Alex Verboon have created a list of all the new settings for Win8 Consumer Preview. You can find them here.

Thursday, February 23, 2012

Policy vs Preferences

I read an interesting post from Darren Mar-Elia about this. I've been thinking about it but I can't articulate it as well as he. So if you ever thought about the question, please look at his blog here.

Thursday, January 05, 2012

Change DNS on multiple computers - Now in PowerShell

I published a script to change DNS on multiple computers a while back (here it is). It was written in VBScript. Now there is an update written in PowerShell by my colleague and friend Jan Egil Ring (PowerShell MVP).

Here is his mail with a link to the module:
--BEGIN--
“Hi Jimmy,

I finally got time to finish the blog-post:


Rather than creating a single script for the specific task I ended up creating a function in PowerShell, including capabilities such as error handling, logging and the option to either replace or add/remove entries from the DNSSearchOrder-list.
I also ended up creating a module I published on Codeplex, since I couldn`t find any complete library for managing network adapters from PowerShell (or other languages for that matter).
So let`s hope people in the community will contribute with more commands to the module…
J (Win 8 will provide native modules for things like this, but I guess they won`t be backward compatible)”
--END--

And here is the Script:

--BEGIN--
I couldn`t resist re-writing your script into PowerShell ;)

It does reset the DNSServerSearchOrder rather than replacing specified IPs, so it`s not exactly the same.




# NAME:Set-DNSServer.ps1
#
# AUTHOR: Jan Egil Ring
# EMAIL: [JImmy removed this]
#
# VERSION HISTORY:
# 1.0 06.10.2011 - Initial release

#Custom variables
$FilePath = "C:\serverNames.txt"
$DNSServerSearchOrder = "10.230.20.9","10.230.20.10"

 foreach ($computer in $FilePath) {

if (Test-Connection -ComputerName $computer -Count 1 -Quiet) {
$NICs = Get-WmiObject -Query "SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = TRUE AND DHCPEnabled = FALSE" -Computer $computer
if ($NICs) {
foreach ($NIC in $NICs) {
if ($NIC.DNSServerSearchorder) {
$NIC.SetDNSServerSearchOrder($DNSServerSearchOrder)
}
}
}

}
else {
Write-Host "Unable to contact $computer"
}
}
--END--

Thursday, October 13, 2011

SCM v2

SCM 2 provides ready-to-deploy policies and DCM configuration packs that are tested and fully supported. Our product baselines are based on Microsoft Security Guide recommendations and industry best practices, allowing you to manage configuration drift, address compliance requirements, and reduce security threats.

Download Security Compliance Manager 2


Sunday, October 02, 2011

MVP Award

I received this in my mail yesterday:

___________
Dear Jimmy Andersson,

Congratulations! We are pleased to present you with the 2011 Microsoft® MVP Award! This award is given to exceptional technical community leaders who actively share their high quality, real world expertise with others. We appreciate your outstanding contributions in Directory Services technical communities during the past year.

___________

This is the 13th year in a row I got honored with this award, and I'm proud of it!

Monday, September 26, 2011

MVA - Microsoft Virtual Academy

http://www.microsoftvirtualacademy.com/GetStarted.aspx

MVA is a training portal that offers you (at present date) the following tracks:

Clustering
Hyper-V
IaaS
Office 365
PaaS
Private Cloud
Public Cloud
SaaS
Security
SQL Azure
System Center
VDI
Virtualization
VMware
Windows Azure

Friday, September 16, 2011

Windows 8 License Fun

When installing the Windows 8 Developer Preview with Tools, this funny license came up. Notice the second row, it's funny :)

More info on Windows 8

Mark Minasi have written an article about Windows 8:
http://www.minasi.com/newsletters/nws1109.htm

Thursday, September 15, 2011

Windows 8

Are you curious about Windows 8?
Take a look at Sean Deuby's article in Windows IT Pro, I'm uncertain if I break NDA at this point so I will direct you to the official article on the Internet. When I'm certain about what I can blog without breaking NDA I will of course blog it :)

http://www.windowsitpro.com/author/5202540/SeanDeuby.aspx

Monday, September 12, 2011

PowerShell Cheat Sheet

On the Windows PowerShell Blog you will find Cheat Sheets for PowerShell.

Kerberos authentication over external trust

Yes, it is possible! See Jorge's blog for details.

Nordic Infrastructure Conference

Welcome to NIC2012!


Our goal is to create the premier event for all IT-professionals in the Nordics, offering broad technical education on Microsoft and 3. party products, tools and services. Our two day event will focus on deep-dives and practical knowledge on the most used products. This means less slides, more hands-on. We will show you the good and the bad sides, we will show you how to solve the most common tasks and challenges, sharing all our experience from the real world, the tips & the tricks.

So if you are deploying, managing, securing and mobilizing Microsoft solutions, NIC is the place to be. We will focus on the key technologies within current and soon-to-be released products, helping you to better solve today's IT-challenges, and preparing for tomorrow's innovations.

http://www.nic2012.com/

Thursday, December 02, 2010

Interactive logon information

I got into some discussions about these 4 attributes and how they work. Here it is:


msDS-FailedInteractiveLogonCount: The total number of failed Ctrl + Alt + Del (C-A-D) logon attempts at a Windows Vista or Windows Server 2008 domain joined member (or higher) since the Last Interactive Logon Information feature was turned on.
Integer

msDS-FailedInteractiveLogonCountAtLastSuccessfulLogon: The total number of failed C-A-D logon attempts at a Windows Vista or Windows Server 2008 domain joined member (or higher) up until the last successful C-A-D logon.
Integer
msDS-LastFailedInteractiveLogonTime: The time that an incorrect password was presented during a C-A-D logon attempt at a Windows Vista or Windows Server 2008 domain joined member (or higher).
Timestamp

msDS-LastSuccessfulInteractiveLogonTime: The time that a successful C-A-D logon occurred at a Windows Vista or Windows Server 2008 domain joined (or higher).
Timestamp

If the and username/password is correct, it writes the timestamp to the msDS-LastSuccessfulInteractiveLogonTime . If the username/password is wrong it will write the timestamp to the msDS-LastFailedInteractiveLogonTime. Then the values of msDS-FailedInteractiveLogonCountAtLastSuccessfulLogon and msDS-FailedInteractiveLogonCount get raised by one (1). For example, if the msDS-FailedInteractiveLogonCount already have 2 it becomes 3.

When it is configured two things will happen:
1) The domain controller writes the information to AD and replicates it.. [Screenshot 1]
2) On the machine the user logs on to (at least Vista or 2008 server (or higher)) a query is sent to display the information at the logon screen. [Screenshot 2]

[Screenshot 1] The information waiting to be replicated to other DCs:

(0) modify CN=Jimmy Andersson,OU=Users,OU=ADS,OU=Services,OU=_Operations,DC=qadvice,DC=prv
1> objectGUID: 1e8979ba-94f8-47fe-83cc-99e9c28fa016
1> instanceType: 0x4 = ( WRITE )
1> msDS-LastSuccessfulInteractiveLogonTime: 2010-11-14 19:43:54 W. Europe Standard Time

[Screenshot 2] The information displayed to the user after a successful logon



What you need to think about:

Each time a user logon it will create replication traffic as you can see in screenshot 1. This information is then replicated to all domain controllers – in large environments this will most likely be an issue. So this feature should be used with caution!

If a RODC authenticates the user, this will happen:
• msDS-LastSuccessfulInteractiveLogonTime will only be written to the RODC and not forwarded to the RWDC
• msDS-LastFailedInteractiveLogonTime is written to the RODC and the RWDC. Then it will be replicated back from the RWDC to the RODC.
• msDS-FailedInteractiveLogonCountAtLastSuccessfulLogon will only be written to the RODC and not forwarded to the RWDC
• msDS-FailedInteractiveLogonCount is written to the RODC and the RWDC. Then it gets replicated back from the RWDC

Note! If you configure this for an OU, but not configure this on the domain controllers the users will not be faced with this error and not be able to logon:

Security policies on this computer are set to display information about the last interactive logon. Windows could not retrieve this information. Please contact your network administrator for assistance.

If a domain controller can’t be located the user will not be able to logon.

If you still see a need to use this feature, this is how you configure it:
Create a GPO and link it to both the domain controllers OU and to the OU you have the clients you want the users to see this logon information on. Of course if you want to be more flexible create two GPOs, one for the domain controllers OU and one for the clients which you then can use groups and filter etc.

Note! Even if you select only a few clients to show this information on, you actually affect all DCs. So even if the users only see this information on a selected number of clients – the information is still written to a DC (for all logons) and then replicates to all DCs. This is because you enable it on the DC(s) and thus all users get affected.

My recommendation:
Only use it when you really need it. Display the information for normal end-users is useless since they won’t understand it – most users will only click OK without reading it anyway…

Wednesday, November 17, 2010

Dcpromo and DNS installation message

Have you ever seen this?
"A delegation for this DNS server cannot be created because the authoritative parent zone cannot be found or it does not run Windows DNS server. If you are integrating with an existing DNS infrastructure, you should manually create a delegation to this DNS server in the parent zone to ensure reliable name resolution from outside the domain “FQDN”. Otherwise, no action is required."
This happens when:
- Dcpromo.exe has been configured to install the DNS server role, and enough delegations do not already exist between DNS servers in the immediate parent DNS zone and the subdomain where you are installing the new DC. And the DC is unable to create delegation to the DNS subdomain on a DNS server that is autoritative for the parent zone.
Do you need to care about it?
Not if you don't have users in other domains (Internet included) that have the need to resolve DNS queries in the local domain.
Why does it happen?
- It will try to create the delegation to ensure name resolution from other domains.
- You can also see this in the forest root when it is immediately subordinate to top-level domains.
- Dcpromo can auto-create this delegation, but only for MS DNS and will fail for non-MS DNS servers.
- If the domain (root) is subordinate to an existing intranet namespace that is owned by non-MS DNS servers such as BIND.
- I also heard that this can happen if the AD domain is registered on the Internet, but the ISP have not created necessary delegation yet.
How to avoid it?
- On your non-MS DNS servers, pre-create the delegation in the parent domain.
- If you have MS DNS servers in the parent domain, make sure you have the necessary permissions to create the delegation in the parent zone.

Saturday, October 02, 2010

MVP Award

I received this in my mail yesterday:

"Dear Jimmy Andersson,


Congratulations! We are pleased to present you with the 2010 Microsoft® MVP Award! This award is given to exceptional technical community leaders who actively share their high quality, real world expertise with others. We appreciate your outstanding contributions in Directory Services technical communities during the past year.
The Microsoft MVP Award provides us the unique opportunity to celebrate and honor your significant contributions and say "Thank you for your technical leadership.""

This is the 12:th year in a row I get honered with this award. I am proud.

Tuesday, September 28, 2010

Active Directory Web Services (ADWS)

This is a service that came with Windows Server 2008 R2 and provides a Web service interface to AD DS, AD LDS and the AD Database Mounting Tool which are running on the same server as ADWS.

ADWS is installed automatically when you add the AD DS or AD LDS role to your server.

What happen if I stop it?
The Powershell module and AD Administrative Center will not be able to access any directory instances on the server. I personally think that in the future even more applications will stop working as well.

Any considerations?
Yes, ADWS requires TCP port 9389 to be open on the servers that run ADWS.

Can I configure how the traffic is handled?
Yes, in the %windir%\ADWS directory there is a file called Microsoft.ActiveDirectory.WebServices.exe.config file you can edit. This is the default values:

Parameter name: MaxConcurrentCalls
Default value: 32
Description: Specifies the maximum number of simultaneous service requests that the ADWS service is configured to process at a given time. Set a higher value for this parameter if the ADWS service on your Windows Server 2008 R2 server must be able to process more than 32 service requests at any given time.

Parameter name: MaxConcurrentSessions
Default value: 500
Description: Specifies the maximum number of client sessions that the ADWS service can accept at any given time. Set this parameter to a higher value if the ADWS service on your Windows Server 2008 R2 server must be able to accept more than 500 concurrent client sessions at any given time.

Parameter name: MaxReceivedMessageSize
Default value: 1 MB
Description: Specifies the maximum message request size, in megabytes (MB), that a client computer can send to the directory service instances that the ADWS service supports. This setting can affect the memory consumption of the ADWS service. For example, if MaxConcurrentCalls is set to 32 and MaxReceivedMessageSize is set to 1 MB, the ADWS service is configured to process a maximum of 32 MB in client message requests at any given time.

Parameter name: MaxStringContentLength
Default value: 32 KB
Description: Specifies the maximum string size, in kilobytes (KB) of a Lightweight Directory Access Protocol (LDAP) attribute that the ADWS service is configured to process in a message request that a client computer sends to a directory service instance that the ADWS service supports. Increasing this value can increase the maximum possible memory consumption of the ADWS service.

Parameter name: MaxPoolConnections
Default value: 10
Description: Specifies the maximum number of LDAP connections for each directory service instance that is used by the ADWS service that is running on a given Windows Server 2008 R2 server.

For example, if MaxPoolConnections on a particular Windows Server 2008 R2 server is set to 10 and there are 3 directory service instances running on this server, ADWS uses a maximum of 10 LDAP connections to each of these directory service instances to process requests that are sent to the ADWS service. Along with MaxConcurrentCalls, this can affect the maximum number of simultaneous requests that the ADWS service can process. Set this parameter to a higher value if you notice that client service requests are timing out while they wait for an LDAP connection to be available to process their request.

Note: To improve performance, the ADWS service on a Windows Server 2008 R2 server maintains a separate LDAP connection pool for every directory service instance that is running on this server. For example if your Windows Server 2008 R2 server is a domain controller (and is, therefore, running the AD DS server role) and also a global catalog server and if it is running two AD LDS instances and one Active Directory Database Mounting Tool instance (a total of five directory service instances), the ADWS service on this Windows Server 2008 R2 server maintains five separate LDAP connection pools. Because a global catalog does not share the same LDAP port as AD DS, it is considered a separate directory instance.

Parameter name: MaxPercentageReservedConnections
Default value: 50%
Description: Specifies the percentage of LDAP connections that are reserved for performing query operations for each directory service instance that the ADWS service supports on a given Windows Server 2008 R2 server. Set this parameter to a higher percentage if the ADWS service on this Windows Server 2008 R2 server is used mostly for running queries.

Parameter name: MaxConnectionsPerUser
Default value: 5
Description: Specifies the maximum number of LDAP connections (to a single directory service instance) that the ADWS service permits to be used at one time for operations that are associated with a single set of client credentials (one user). Set this parameter to a higher value if you are experiencing more than five concurrent client requests by one user to a single directory service instance running on your Windows Server 2008 R2 server. The value of MaxConnectionsPerUser cannot be greater than the value of MaxPoolConnections. If the value of MaxConnectionsPerUser is equal to the value of MaxPoolConnections, it will allow a single set of client credentials (for a single client computer) to consume all available LDAP connections for a given directory service instance.

Parameter name: MaxEnumContextExpiration
Default value: 30 minutes
Description: Specifies the maximum allowed time period during which the ADWS service processes and retrieves the results of a query request from a client computer.

Caution: Changing the default value of this parameter is strongly discouraged. Most of the search results are returned within 30 minutes.

Parameter name: MaxPullTimeout
Default value: 2 minutes
Description: Specifies the maximum allowed time-out value that a client computer can set when it retrieves one page of search results. Set this parameter to a higher value if slow wide area network (WAN) traffic results in a time-out value for returning one page of search results that is longer than two minutes

Note: The ADWS service processes search requests from client computers in the following manner:
- A client submits a search request.
- The ADWS service establishes a search context and returns a search context ID to the client computer.
- Using this search context ID, the client computer issues a page request to extract the search results specifying how many LDAP objects can be returned per page.

MaxPullTimeout controls the maximum amount of time a client can ask the ADWS service to spend retrieving a page of results, while MaxEnumContextExpiration is the maximum time that the search context can be kept open.

Parameter name: MaxEnumCtxsPerSession
Default value: 5
Description: Specifies the maximum number of search requests (search contexts) that can be submitted over a single client session to the ADWS service.

Parameter name: MaxEnumCtxsTotal
Default value: 100
Description: Specifies the maximum number of search requests (search contexts) that can be submitted over all active client sessions to the ADWS service.

Parameter name: MaxGroupOrMemberEntries
Default value: 5000
Description: Specifies the maximum number of group members (recursive or non-recursive), group memberships, and authorization groups that can be retrieved by the Active Directory module Get-ADGroupMember, Get-ADPrincipalGroupMembership, and Get-ADAccountAuthorizationGroup cmdlets. Set this parameter to a higher value if you anticipate these cmdlets to return more than 5000 results in your environment.

Note: This setting can affect the memory consumption of the ADWS service.
This configuration parameter is applicable only to the three Active Directory module cmdlets mentioned above.
If your operation returns an exceptionally large results set, you might run into a non-configurable 5-minute timeout.

Parameter name: OperationTimeout
Default value: 2 minutes
Description: Specifies the timeout limit for any ADWS service-based query request. Set this parameter to a higher value if you expect your query to return an exceptionally large results set that might take longer than 2 minutes to retrieve.

Recommendations:
- Let ADWS run on all domain controllers.
- Don't edit the config file unless you really need to.
- Do remember that this config file is not replicated. You need to edit it on all domain controllers.

Down-level servers (Windows Server 2003 SP2, R2, 2008, 2008 SP2):
The Active Directory Management Gateway Service provides the same functionality as ADWS on 2008 R2. It is available as a download on the Microsoft web site.

Are there absolutely no differences between ADWS and AD Management Gateway Service?
Yes, there is one difference that you will see, the AD Management Gateway Service do not support instances of the AD Database Mounting Tool running on Windows Server 2008.

Authentication Mechanism Assurance

Many people ask me about this feature and how it works. Let me first give an example scenario:


Let's say you have a user named Mark, this user is a member of the department Section5. Section5 deals with classified development. In the classical Windows way, you would create a group, let's name it "S5-Classified" (stupid name but it is just an example) and add the users within the department Section5 to it.

Let's say you have a file server with a share with top secret material, and you want only the members of the group S5-Classified to have access to it. You obviously grant the S5-Classified group the needed access, right?

This is all good, except that you now want them only to be able to access the files when they logon with a certifiacate-based logon. I.e. they should not be able to access it without the smart-card.

So this is what it is all about, granting access based on the logon method. With certificate-based logon you will get a certain access, without a smart-card - you get less access.

What happens behind the GUI:
First, it is not enabled by default in Windows Server 2008 R2 and it requires DFL Windows Server 2008 R2. What happens when you enable it is that authentication mechanism assurance adds a universal group (which you as an admin designate) to the user's access token when the user logon with a certificate-based method.

So if access is granted based on the designated universal group, the user Mark have only access if using a certificate-based logon. If using another logon method the universal group will not be present in the access token, and thus no access.

Thursday, August 12, 2010

Powershell script to put migrated users into a group

My friend Tony Murray has written a very good script that helps you keep track of migrated users that I wanted to share:

Note: I couldn't get the tabs in so it looks a little funny :(

-Script Begins-

#########################################################

#
# Name: SIDHistoryBasedGroupMembership.ps1
# Author: Tony Murray
# Version: 1.0
# Date: 11/07/2010
# Comment: PowerShell 2.0 script to
# populate group membership based on sIDHistory values
#
#########################################################


#Import the Active Directory Powershell Module
Import-Module ActiveDirectory -ErrorAction SilentlyContinue


#Create a new Event log source for the script (only needs to be run once)
New-EventLog -logName Application -Source "Legacy Users Group Management" `
-ErrorAction SilentlyContinue


$SearchBase = "OU=User Objects,DC=fabrikam,DC=local"
$OUArr = Get-ADUser -LDAPFilter "(samaccounttype=805306368)" `
-SearchBase $SearchBase -SearchScope SubTree


# Now we need the domain security identifier or at least a portion of it
$DomSID = "S-1-5-21-1584567894-2535104369-4141123456"


$Group = "Legacy Users"
$MbrArr = get-adgroupmember -identity $Group


# Loop through the Users found beneach the OU tree
# and check to see if the user is already
# a member of the group. If so, do nothing.
# If not, then add the user as a member.
Foreach ($User in $OUArr)
{
$object = [ADSI]"ldap://$User/"
$objectsidh = $object.sIDHistory.value
If (!$objectsidh)
{
# write-host "sIDHistory is blank"
}
Else
{
$objectsidh = $Object.getex(“sidhistory”)
trap
{
#write-host "Error: $_"
continue
}
foreach($sid in $objectSidh)
{
$sidh = new-object System.Security.Principal.SecurityIdentifier $sid,0
if ($sidh -Match $DomSID)
{
if ($MbrArr -Match $User.distinguishedName)
{
#The user is already member - do nothing
}
else
{
# We need to add the user as a member
write-eventlog -logname Application `
-source "Legacy Users Group Management" `
-eventID 3001 -entrytype Information -message "$User added to $Group"
Add-ADGroupMember -Identity $Group -Members $User
}
}
else
{
# No match with sidHistory - do nothing
}
}
}
}
 
-Script Ends-

Friday, July 23, 2010

TechEd sessions

If you couldn't attend, you will find the sessions here: http://www.msteched.com/

Sunday, July 18, 2010

Tired

And people say I look funny when I'm tired and sleep with the laptop on my knees.....

New member in the Andersson family

Yep, there is a new member in our family. A very charming Boarder Collie that is 8 weeks and 4 days. She will most certainly make me leave the computer once in a while :)

Monday, April 12, 2010

Windows Summit 2010

Attend Windows Summit 2010: May 25–27

This is a special opportunity to learn—straight from the Windows team—how you can best use Windows 7 and Internet Explorer to enable great solutions for your customers. This three day event takes place at the Microsoft Conference Center on Microsoft's campus in Redmond, WA and is designed for people who engineer and test Windows 7 PCs, devices, and software. Take advantage of this uniquely intimate event on the Microsoft campus to network with Microsoft technical experts and leaders at breakout sessions, chalk talks, and an Ask the Experts evening and social event.

More info here.

Monday, March 15, 2010

TechDays

I will speak on TechDays this year together with my colleague Fredrik PÃ¥lerud (scroll down and you'll see him). If you want to know what it is, see this. TechDays is a Microsoft Sweden event and is held once per year. This year it is fully booked already so I'm looking forward to it!

Crayon also have a booth that we will spend as much time as possible in, please come and join us! And despite what the Crayon website says - we do have some seriously good consultants (they just haven't updated it with the consultant department yet....).

Friday, February 19, 2010

Install DFS Management Console - when you can't use the mouse

ServerManagerCmd -install RSAT-DFS-Mgmt-Con

Installing DFS replication - when you can't use the mouse

If you want to install DFS replication on web edition or server core. You need to do it from a command prompt:

OCSetup DFSR-Infrastructure-ServerEdition


or:
 
ServerManagerCmd -install FS-DFS-Replication

Tuesday, February 09, 2010

Protect "old" OUs from accidental deletion

In Win 2K8 and newer. There is a a check-box you can set to protect an OU from accidental deletion. This is good, but if you don't use ADUC in Win 2K8 (or R2) it will not be set by default. Also if you upgraded or migrated to a Win 2K8 (or R2) it won't be set automagically on "old" objects. So here is two ways of doing it.

for /f "tokens=*" %i in ('dsquery ou -limit 0') do dsacls %i /d everyone:SDDT

or:

Get-ADOrganizationalUnit -filter * |

Set-ADOrganizationalUnit -ProtectedFromAccidentalDeletion $true
 
(the above should be one line)
 
Thank you Ulf for posting these two one-liners!

Friday, January 22, 2010

Defining a new attribute - version 2

My colleague, Fredrik PÃ¥lerud, just saw what I blogged and he has another recommendation. Use Active Roles and you don't have to touch the actual Schema. Wanna lear more.... Click here.

Defining a new attribute

I just stumbled over a pretty good article. It describes how to define a new attribute when you extend the Schema. Take a look at it if you haven't memorized it yet....

Outlook signature based on user info from AD

My colleague from Crayon Norway, Jan Egil Ring, have written a cool Powershell script that creates an Outlook signature based on information from AD. Take a look at it, it is posted here. 

Friday, January 15, 2010

Enable Recycle Bin - with Powershell

This is the Powershell way to enable Recycle Bin in a domain called DEMO.PRV:

Enable-ADOptionalFeature –Identity ‘CN=Recycle Bin Feature,CN=Optional Features,CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,DC=demo,DC=prv’ –Scope ForestOrConfigurationSet –Target ‘demo.prv’

Enable Recycle Bin - but not with Powershell

A question from yesterday: "Must I use Powershell to enable Recycle Bin in AD?"
The answer is: No.

You can also use LDP to do it. What you need to know is the GUID of the Recycle Bin and where to add it.

To find the GUID you need to browse to:
CN=Recycle Bin Feature,CN=Optional Features,CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,DC=domainName,DC=xxx

And look at the msDS-OptionalFeatureGUID value (which is 766ddcd8-acd0-445e-f3b9-a7f9b6744f2a).

Then you need to modify the CN=Partitions,CN=Configuration, DC=domainName,DC=xxx container:
1. Right-click it and select: "Modify"
2. Delete everything in the "DN:" box, it MUST be empty!
3. In the "Edit Entry Attribute:" box type: enableOptionalFeature
4. In the "Values" box type: CN=Partitions,CN=Configuration, DC=domainName,DC=xxx:766ddcd8-acd0-445e-f3b9-a7f9b6744f2a
5. In "Operation" you select "Add" click "Enter" and last you click "Run"

You have now enabled the Recycle Bin feature in AD!

Note - this is a Windows 2008 R2 feature so it won't work on legacy OS. You must also replace domainName and xxx with whatever your environment is called.

Wednesday, January 06, 2010

Tuesday, January 05, 2010

Windows 7 God Mode

My good friend Wolfgang Schedlbauer sent me a mail today. The subject was "GodMode in Windows 7". So that got my attention and I needed to try it. It is cool! If you want to know what it is and try it (below text copy/pasted from his mail):


What is God Mode? This is a secret Windows 7 Feature (If you can call so!!), which provides you an extended control panel to control your machine.


Here are the Steps to invoke the God Mode:

Create a new folder (right-click and click on “New Folder”). Right-click on the folder and click on rename, copy and paste this: GodMode.{ED7BA470-8E54-465E-825C-99712043E01C}

This folder will now be a shortcut to the Windows 7 God Mode. The GodMode allows you to quickly access many Windows 7 functions via a GUI.

Thursday, December 17, 2009

New job!

1 minute ago, I signed the employment contract for Crayon (http://www.crayon.no/, http://www.crayon.se/). I will start the first of January as Crayon Sweden's Chief Architect for Microsoft technology.

So if you want me as a consultant, you contact Crayon.

Friday, November 20, 2009

Restore of an object or subtree

I've been asked several times how to get an object or subtree of objects back if an accidental deletion happened and you have one DC that still have the objects. In other words mark these objects as authoritative so they replicate back to the DCs that have them deleted. This is usual in a lag site scenario, or if you are lucky to find a DC that haven't already delete the object(s).

So here is a step-by-step on Windows 2008, note that this is not applicable for versions lower than 2008.


1. Stop relication on a DC that have the object(s) with repadmin. I usually stop both inbound and outbound to be safe:
- Repadmin /options +disable_inbound_repl
- Repadmin /options +disable_outbound_repl

2. Stop AD Service. This will also stop the following services:
- File Replication
- Kerberos Key Distribution Center
- Intersite Messaging
- DNS Server
- DFS Replication

3. Set instance:
- Ntdsutil
- Activate instance NTDS

4. Authoritative Restore (while in ntdsutil):
- Authoritative restore
- Restore subtree ou=dr-test,dc=qadvice,dc=prv

Example screenshot:
authoritative restore: restore subtree ou=dr-test,dc=qadvice,dc=prv
Opening DIT database... Done.

The current time is 11-20-09 12:35.45.
Most recent database update occured at 11-20-09 12:32.09.
Increasing attribute version numbers by 100000.
Counting records that need updating...
Records found: 0000001001
Done.

Found 1001 records to update.
Updating records...
Records remaining: 0000000000
Done.

Successfully updated 1001 records.
The following text file with a list of authoritatively restored objects has been created in the current working directory:
ar_20091120-123545_objects.txt
None of the specified objects have back-links in this domain. No link restore file has been created.
Authoritative Restore completed successfully.

5. Start AD and related services (if they don't start automatically)

6. Enable replication on the DC:
- Repadmin /options -disable_inbound_repl
- Repadmin /options -disable_outbound_repl

Tuesday, October 06, 2009

MVP Award. I received this in my mail Oct 1st:

"Dear Jimmy Andersson,Congratulations!

We are pleased to present you with the 2009 Microsoft® MVP Award! This award is given to exceptional technical community leaders who actively share their high quality, real world expertise with others. We appreciate your outstanding contributions in Directory Services technical communities during the past year."

I'm very glad and proud of it. This is the 11th year in a row!

Friday, August 07, 2009

TEC Europe

I just decided to attend TEC Europe in September. It will be held in Berlin at the Hilton, September 14-16.
Hope to see you there!

Thursday, July 30, 2009

Sooz arrived

Sooz arrived, picked her up at the airport. And guess what..... Yes, she arrives without the bag, it is still in Copenhagen and we hope it will arrive sometime soon. Tomorrow we're going on a road trip to Sundsvall so I really hope she gets her bag tonight....

Wednesday, July 29, 2009

Find account based on a given SID

Here is some code that will find the account based on a given SID:

-Script Begins-
'============================================================
' NAME: find-Account.vbs
' AUTHOR: Jimmy Andersson, Q Advice AB
' DATE: 21/04/2009
' Version: 1.0 - initial version
' USAGE: cscript find-Account.vbs
'============================================================
Option Explicit

'============================================================
'==== Declare variables and sets objWMIService
'============================================================
Dim strComputer, objWMIService, objAccount
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

'===========================================================
'==== Below code finds the account based on a given
'==== SID (both local and domain accounts)
'===========================================================
Set objAccount = objWMIService.Get _
("Win32_SID.SID='S-1-5-21-842925246-725345543-682003330-4474'")
wScript.Echo objAccount.ReferencedDomainName &_
"\" & objAccount.AccountName
-Script Ends-

A way of finding the local admin account by searching SIDs

Let's say you don't know the account name for the local admin account. The below code will find it for you. This is really good to have if a customer used the "oh-not-so-good-way-to-apply-security" approach.
I actually had a customer (before I came along and changed it) randomize the renaming of the local admin on their workstations....
Do I need to say that they didn't have a log. And even more "strange" is that they actually created 20+ local accounts just to confuse a potential bad guy.....
I will not start to rant about what I think of this approach. Never the less I had to find all the local admin accounts on their workstations. So I wrote some code that I fired off remotely and logged the information in a secure place. The basis of that code is below:
(as usual wrapping might be an issue)

-Script Begins-
'============================================================
' NAME: find-AdminName.vbs
' AUTHOR: Jimmy Andersson, Q Advice AB
' DATE: 21/04/2009
' Version: 1.0 - initial version
' USAGE: cscript find-AdminName.vbs
'============================================================
Option Explicit

'============================================================
'==== Declare variables and sets objWMIService
'============================================================
Dim strComputer, objWMIService, objAccount, colAccounts

strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

'===========================================================
'==== Below code finds the local ADMINISTRATOR account
'==== by searching the SIDs of local accounts
'===========================================================
Set colAccounts = objWMIService.ExecQuery _
("Select * From Win32_UserAccount Where LocalAccount = TRUE")
For Each objAccount in colAccountsIf Left (objAccount.SID, 6) = "S-1-5-" and Right(objAccount.SID, 4) = "-500" Then
Call getInfo
End If
Next

'===========================================================
'==== Function to get properties
'===========================================================
Function getInfo
wScript.Echo "Name: " & objAccount.Name
wScript.Echo "SID: " & objAccount.SID
wScript.Echo "Description: " & objAccount.Description
wScript.Echo "Disabled: " & objAccount.Disabled
wScript.Echo "Pwd Expires: " & objAccount.PasswordExpires
wScript.Echo "Pwd Required: " & objAccount.PasswordRequired
wScript.Echo "Pwd Changeable: " & objAccount.PasswordChangeable
End Function
-Script Ends-

How to get the SID of an account

Someone asked me how to write a script that will show you the SID and some other "stuff" of a specified username. So here it is, really simple and fast to do. The below will show you:
- name (which you need to know in advance)
- SID
- Description
- If it is disabled or not
- If the password expires
- If a password is required
- If the password can be changed.

-Script Begins-
'============================================================
' NAME: findSID-Name.vbs
' AUTHOR: Jimmy Andersson, Q Advice AB
' DATE: 21/04/2009
' Version: 1.0 - initial version
' USAGE: cscript findSID-Name.vbs
'============================================================

Option Explicit

'============================================================
'==== Declare variables and sets objWMIService
'============================================================
Dim strComputer, objWMIService, objAccount
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer &
"\root\cimv2")

'============================================================
'==== Below code gets the SID of a specified account.
'==== NOTE: If you specify a domain name instead of a computer name you'll
'==== get the SID of a domain account. E.g. name='admin',domain='root' '================'===========================================
Set objAccount =_
objWMIService.Get("Win32_UserAccount.Name='x-admin',Domain='client001'")
Call getInfo


'===========================================================
'==== Function to get properties
'===========================================================
Function getInfo
wScript.Echo "Name: " & objAccount.Name
wScript.Echo "SID: " & objAccount.SID
wScript.Echo "Description: " & objAccount.Description
wScript.Echo "Disabled: " & objAccount.Disabled
wScript.Echo "Pwd Expires: " & objAccount.PasswordExpires
wScript.Echo "Pwd Required: " & objAccount.PasswordRequired
wScript.Echo "Pwd Changeable: " & objAccount.PasswordChangeable
End Function
-Script Ends-

How to show color indices in Excel with VBScript

Ok, someone asked me how to find out the color indices in Excel via Script. So here it goes:

(as always, formatting and word wrap might not work.....And you need Excel installed on the machine where the code executes of course)

-Script Begins-

Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = TrueSet
objWorkbook = objExcel.Workbooks.Add()
Set objWorksheet = objWorkbook.Worksheets(1)

For i = 1 to 14
objExcel.Cells(i, 1).Value = i
objExcel.Cells(i, 2).Interior.ColorIndex = i
Next

For i = 15 to 28
objExcel.Cells(i - 14, 3).Value = i
objExcel.Cells(i - 14, 4).Interior.ColorIndex = i
Next

For i = 29 to 42
objExcel.Cells(i - 28, 5).Value = i
objExcel.Cells(i - 28, 6).Interior.ColorIndex = i
Next

For i = 43 to 56
objExcel.Cells(i - 42, 7).Value = i
objExcel.Cells(i - 42, 8).Interior.ColorIndex = i
Next

-Script Ends-

Back from Philly

Came back from Philly and I must say that I had a great time!
It was really nice to meet Laura and Mark again. Their new place is really nice and have everything you need. Including a very nice pub (Charlie's) just around the corner!

All in all - time well spent, good food, good drinks! Hopefully I'll see them again in December in New York!

Now I'm getting ready for Sooze to come visit us tomorrow. That will also be loads of fun, travelling around Sweden and then Germany. Hopefully we have the time to stop by Zürich as well....

Ok, carry on! :)

Wednesday, July 22, 2009

"I want to look after old people"

Nick, you are old. Get over it :)

For you that don't know us, Nick is my mate and I can take the Mickey out of him if I want!

Philly

Ok, arrived in Philly. Mark picked me up at the airport but not my bag... Read Mark's blog for details. Anyway, I'm here and we're having fun!

As always, good food an wine is a given!

Sunday, July 19, 2009

Getting quick info from systems

One thing that is pretty common when you get to a new customer is that they usually have no clue what systems they actually have on their network.
In most cases not all servers are members of AD so that is the reason I use an input list instead of getting all the computer objects from AD and then filter on OS, or specify a "top" OU and then search all computer objects from that OU and then all sub-OUs. This can of course be easily changed in the below script to do just that if you want, I might even post how to do it later... :)

The second thing is that when I wrote this, I actually just needed the info to be showed on the screen. Which is why I didn't created an output file and saved it directly to it (here I just pipe it). I will post a function how to create an output file later and the below script can easily be changed for this as well.


Do note that I couldn't get proper formatting (especially TAB) in this post so the script might look a bit strange. Also note that line breaks are not always correct, so test it first in your lab! I take NO responsibility for the script and it is your responsibility to test it in a lab environment!

-Script Begins-
'============================================================
' NAME: quickInfo.vbs
' AUTHOR: Jimmy Andersson, Q Advice AB
' DATE: 1/12/2008
' Version: 1.0 - initial version
'
' COMMENT: Used to find out settings remotely.
' You need to pipe the output to a text file (see below usage example) that you can
' open in Excel. It will be delimited with semicolons.
' It will do a ping test before trying to connect' to the remote machine.
'
' USAGE: cscript quickInfo.vbs > output.txt
'
' NOTE: If you don't have access it will just move on ' to the next one in the list.
'
'============================================================
On Error Resume Next

'============================================================

'====== Header ===============================================
'============================================================
wScript.Echo "Hostname;Manufacturer;Model;OS;Build;SP;Installed;Last Reboot;Distributed;NIC;MAC;DHCP Enabled;DHCP Server;IP;Subnet;Default Gateway;WINS1; WINS2;DNS"

'============================================================
'====== Specify input file and open it ===============================
'============================================================
' Input file with the server names
strFilename = "C:\_scripts\servers.txt"

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTS = objFSO.OpenTextFile(strFilename)

Do Until objTS.AtEndOfStream

strComputer = objTS.ReadLine
DoObject strComputer

Loop

objTS.Close

'============================================================
'====== Sub that collects data ====================================
'============================================================
Sub DoObject(strComputer)

strPingStatus = PingStatus(strComputer)

If strPingStatus = "Success" Then
Set objWMI = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colOS = objWMI.ExecQuery("SELECT * FROM Win32_OperatingSystem")

For Each objOS In colOS
Set colHW = objWMI.ExecQuery("SELECT * FROM Win32_ComputerSystem",,48)

For Each hwItem in colHW
strHW = hwItem.Manufacturer
strModel = hwItem.Model

Set colItem = objWMI.ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = TRUE",,48)

For Each objItem In colItem

strInfo = objOS.CSName & ";" & strHW & ";" & strModel & ";" & objOS.Caption &_
";" & objOS.BuildNumber & ";" & objOS.CSDVersion & ";" & objOS.InstallDate &_
";" & objOS.LastBootUpTime & ";" & objOS.Distributed & ";" &_
objItem.Caption & ";" & objItem.MACAddress & ";" & objItem.DHCPEnabled &_
";" & objItem.DHCPServer & ";" & Join(objItem.IPAddress, ",") & ";" &_
Join(objItem.IPSubnet, ",") & ";" & Join(objItem.DefaultIPGateway, ",") & ";" &_
objItem.WINSPrimaryServer & ";" & objItem.WINSSecondaryServer & ";" &_
Join(objItem.DNSServerSearchOrder, ",")

wScript.Echo strInfo
Next
Next
Next

Else
wScript.Echo strComputer & ";" & "Didn't answer ping"
End If
End Sub

'============================================================
'====== Function for w32_PingStatus WMI class =======================
'============================================================
Function PingStatus(strComputer)
On Error Resume Next

' Uses the local machine as the system to ping from
strWorkstation = "."

Set objWMIService = GetObject("winmgmts:" _& "{impersonationLevel=impersonate}!\\" & strWorkstation & "\root\cimv2")Set colPings = objWMIService.ExecQuery _
("SELECT * FROM Win32_PingStatus WHERE Address = '" & strComputer & "'")

For Each objPing in colPings ' Return codes
Select Case objPing.StatusCode

Case 0 PingStatus = "Success"
Case 11001 PingStatus = "Status code 11001 - Buffer Too Small"
Case 11002 PingStatus = "Status code 11002 - Destination Net Unreachable"
Case 11003 PingStatus = "Status code 11003 - Destination Host Unreachable"
Case 11004 PingStatus = "Status code 11004 - Destination Protocol Unreachable"
Case 11005 PingStatus = "Status code 11005 - Destination Port Unreachable"
Case 11006 PingStatus = "Status code 11006 - No Resources"
Case 11007 PingStatus = "Status code 11007 - Bad Option"
Case 11008 PingStatus = "Status code 11008 - Hardware Error"
Case 11009 PingStatus = "Status code 11009 - Packet Too Big"
Case 11010 PingStatus = "Status code 11010 - Request Timed Out"
Case 11011 PingStatus = "Status code 11011 - Bad Request"
Case 11012 PingStatus = "Status code 11012 - Bad Route"
Case 11013 PingStatus = "Status code 11013 - TimeToLive Expired Transit"
Case 11014 PingStatus = "Status code 11014 - TimeToLive Expired Reassembly"
Case 11015 PingStatus = "Status code 11015 - Parameter Problem"
Case 11016 PingStatus = "Status code 11016 - Source Quench"
Case 11017 PingStatus = "Status code 11017 - Option Too Big"
Case 11018 PingStatus = "Status code 11018 - Bad Destination"
Case 11032 PingStatus = "Status code 11032 - Negotiating IPSEC"
Case 11050 PingStatus = "Status code 11050 - General Failure"
Case Else PingStatus = "Status code " & objPing.StatusCode & _
" - Unable to determine cause of failure."
End Select
Next
End Function

-Script Ends-


Philadelphia

Tomorrow morning I'm off to Philly! :)

Going to spend some time with the old boy Mark for a few days. After his move to the States it's not that often we have the chance to meet up and hang out. But this week it all worked out!

I expect only three things:
- Good wine
- Good food
- Fun!

If you know us, you know how to get in touch if you're in town.

Tuesday, July 14, 2009

Change DNS on multiple computers

Ok, here is the background. We needed to get rid of some old hardware and replace them with new kit. These servers was DC/DNS and unfortunately we couldn't re-use the IP addresses which meant that all the DNS settings on the servers (the clients used DHCP) needed to get updated.

My client at the time was planning to do this manually, which was not smart at all. Even though their server park was only about 900 servers. So what to do? Obviously scripting was the answer so I put this little script together for them.

Do note that I couldn't get proper formatting (especially TAB) in this post so the script might look a bit strange. Also note that line breaks are not always correct, so test it first in your lab! I take NO responsibility for the script and it is your responsibility to test it in a lab environment!

-Script Begins-
'============================================================
' NAME: replaceDNS_Server.vbs
'
' AUTHOR: Jimmy Andersson, Q Advice AB
' DATE: 19/11/2008
' Version: 1.0 - initial version
'
' COMMENT: Used to replace an IP entry for the DNS settings with a new IP. It will
' do a ping test before trying to connect to the remote machine. Do note that it
' ONLY replaces the IP if it is found, if it can't find the IP nothing will happen
' and it will also return the name of the machine it didn't find it on. If a NIC is
' DHCP ENABLED it will not change anything on that particular NIC.
'
' USAGE: cscript ReplaceDNS_Server.vbs
'
' NOTE: If you don't have access it will just move on to the next one in the list.
' If you want to save the output' pipe it to a text file.
' Example: cscript ReplaceDNS_Server.vbs > output.txt
'============================================================

On Error Resume Next

'============================================================

'====== Specify input file and open it - One computer name per row ========
'============================================================
strFilename = "C:\serverNames.txt"

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTS = objFSO.OpenTextFile(strFilename)

Do Until objTS.AtEndOfStream
strComputer = objTS.ReadLine
DoObject strComputer
Loop
objTS.Close

'============================================================
'====== Sub to replace a DNS entry ================================
'============================================================
Sub DoObject(strComputer)

strOldDNSServer = "10.80.255.122" ' Specify which DNS IP that should be replaced

strNewDNSServer = "10.80.255.206" ' Specify the new DNS IP

' Run ping test before starting to run WMI queries
strPingStatus = PingStatus(strComputer)
If strPingStatus = "Success" Then ' See return codes in the Function

Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

' Only do changes if IP is enabled and DHCP is not used
Set colNicConfigs = objWMIService.ExecQuery _
("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = TRUE AND DHCPEnabled = FALSE")

For Each objNicConfig In colNicConfigs
wScript.Echo VbCrLf & "Computer: " & strComputer
wScript.Echo VbCrLf & " Network Adapter " & objNicConfig.Index
arrDNSServerSearchOrder = objNicConfig.DNSServerSearchOrder

wScript.Echo " DNS Server Search Order - Before:"
If Not IsNull(objNicConfig.DNSServerSearchOrder) Then
For Each strDNSServer In objNicConfig.DNSServerSearchOrder
wScript.Echo " " & strDNSServer
Next
End If

blnFound = 0
For i = 0 to UBound(arrDNSServerSearchOrder)
If arrDNSServerSearchOrder(i) = strOldDNSServer Then
arrDNSServerSearchOrder(i) = strNewDNSServer
blnFound = 1
End If
Next

If blnFound Then
retSetDNS = objNicConfig.SetDNSServerSearchOrder(arrDNSServerSearchOrder)
If retSetDNS = 0 Then
wScript.Echo " Replaced " & strOldDNSServer & " with " & _
strNewDNSServer & " in DNS search order."

Else
wScript.Echo " Unable to change DNS server search order."
End If

Else
WScript.Echo " DNS server " & strOldDNSServer & " not found."
End If
Next

Set colNicConfigs = objWMIService.ExecQuery _
("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = TRUE")
For Each objNicConfig In colNicConfigs
wScript.Echo VbCrLf & "Computer: " & strComputer & " -- " & "DHCP Enabled => NO changes done."
wScript.Echo VbCrLf & String(80, "-")
Next

Else
wScript.Echo VBCrLf & "Computer: " & strComputer & " -- " & "Didn't answer ping => NO changes done."

' Return which machines that didn't answered on ping
wScript.Echo VbCrLf & String(80, "-")
End If

End Sub

'============================================================
'====== Function for w32_PingStatus WMI class =======================
'============================================================
Function PingStatus(strComputer)
On Error Resume Next

' Uses the local machine as the system to ping from
strWorkstation = "."


Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strWorkstation & "\root\cimv2")

Set colPings = objWMIService.ExecQuery _
("SELECT * FROM Win32_PingStatus WHERE Address = '" & strComputer & "'")


For Each objPing in colPings ' Return codes
Select Case objPing.StatusCode

Case 0 PingStatus = "Success"
Case 11001 PingStatus = "Status code 11001 - Buffer Too Small"
Case 11002 PingStatus = "Status code 11002 - Destination Net Unreachable"
Case 11003 PingStatus = "Status code 11003 - Destination Host Unreachable"
Case 11004 PingStatus = "Status code 11004 - Destination Protocol Unreachable"
Case 11005 PingStatus = "Status code 11005 - Destination Port Unreachable"
Case 11006 PingStatus = "Status code 11006 - No Resources"
Case 11007 PingStatus = "Status code 11007 - Bad Option"
Case 11008 PingStatus = "Status code 11008 - Hardware Error"
Case 11009 PingStatus = "Status code 11009 - Packet Too Big"
Case 11010 PingStatus = "Status code 11010 - Request Timed Out"
Case 11011 PingStatus = "Status code 11011 - Bad Request"
Case 11012 PingStatus = "Status code 11012 - Bad Route"
Case 11013 PingStatus = "Status code 11013 - TimeToLive Expired Transit"
Case 11014 PingStatus = "Status code 11014 - TimeToLive Expired Reassembly"
Case 11015 PingStatus = "Status code 11015 - Parameter Problem"
Case 11016 PingStatus = "Status code 11016 - Source Quench"
Case 11017 PingStatus = "Status code 11017 - Option Too Big"
Case 11018 PingStatus = "Status code 11018 - Bad Destination"
Case 11032 PingStatus = "Status code 11032 - Negotiating IPSEC"
Case 11050 PingStatus = "Status code 11050 - General Failure"
Case Else PingStatus = "Status code " & objPing.StatusCode & _
" - Unable to determine cause of failure."
End Select
Next

End Function

-Script Ends-