Category Archives: Windows

Few PowerShell Functions Around Windows Security

Written by Tao Yang

As parts of the PowerShell project that I’m currently working on, with the help with other people’s contribution in various forums and blogs, I have produced few PowerShell functions around Windows security:

Validate Credential

function Validate-Credential($Cred)
$UserName = $Cred.Username
$Password = $Cred.GetNetworkCredential().Password
Add-Type -assemblyname System.DirectoryServices.AccountManagement
$DS = New-Object System.DirectoryServices.AccountManagement.PrincipalContext([System.DirectoryServices.AccountManagement.ContextType]::Machine)
Try {
$ValidCredential = $DS.ValidateCredentials($UserName, $Password)
} Catch {
#if the account does not have required logon rights to the local machine, validation failed.
$ValidCredential = $false
Return $ValidCredential


$MyCredential = Get-Credential

$ValidCredential = Validate-Credential $MyCredential

Get Current User Name

function Get-CurrentUser
$me = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
Return $me


$me = Get-CurrentUser

Check If Current User has Local Admin Rights

function AmI-LocalAdmin
return ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")


$IAmAdmin = AmI-LocalAdmin


Check if a user is a member of a group

function Check-GroupMembership ([System.Security.Principal.WindowsIdentity]$User, [string]$GroupName)
$WindowsPrincipal = New-Object System.Security.Principal.WindowsPrincipal($User)

$bIsMember = $true
} else {
$bIsMember = $false
return $bIsMember


#Current User:

$me = [System.Security.Principal.WindowsIdentity]::GetCurrent()

$group = “\domain admins”

$IsMember = Check-GroupMembership $me $group

#Another User (Using User Principal Name @):

$user = new-object"")

$group = “\domain admins”

$IsMember = Check-GroupMembership $user $group

Get Local Machine’s SID

function Get-LocalMachineSID
$LocalAdmin = Get-WmiObject -query "SELECT * FROM Win32_UserAccount WHERE domain='$env:computername' AND SID LIKE '%-500'"
$MachineSID = $localAdmin.SID.TrimEnd("-500")
Return $MachineSID


$LocalMachineSID = Get-LocalMachineSID

Check If an account is a domain account (as opposed to local account)

Note: This function also requires the Get-LocalMachineSID function listed above

Function Is-DomainAccount ([System.Security.Principal.WindowsIdentity]$User)
$LocalMachineSID = Get-LocalMachineSID
if ($User.user.value -ine $LocalMachineSID)
$bIsDomainAccount = $true
} else {
$bIsDomainAccount = $false


#Current User:

$me = [System.Security.Principal.WindowsIdentity]::GetCurrent()

$IsDomainAccount = Is-DomainAccount $me

#Another User (Using User Principal Name @):

$user = new-object<a href=""></a>)

$IsDomainAccount = Is-DomainAccount $user

My Observation on SCCM Clients BITS Settings

Written by Tao Yang

Yesterday, while we were reviewing the SCCM (2007 R3) client BITS settings at work, we (my team) have some interesting findings with SCCM client’s BITS settings.

We found when the BITS bandwidth throttling settings are configured for a SCCM primary site. SCCM clients get the policy and write the settings into Windows local policy:

SCCM Computer Client Agent BITS Settings:


BITS Settings from SCCM Client’s Windows local policy (Local Policy –>Computer Configuration –>Administrative Templates –>Network –>Background Intelligent Transfer Service (BITS) –>Limit the maximum network bandwidth for BITS background transfers):


As you can see, the SCCM site setting is identical to SCCM client’s local policy. SCCM 2007 Unleashed has explained the client BITS settings. You can read about it on Google Books HERE.

The book did not state and explain the SCCM client actually WRITES the SCCM site’s BITS policy into SCCM client’s Windows local group policy object (GPO). So I did below tests IN ORDER in my home SCCM 2007 R3 AND SCCM 2012 RTM test environments to work out the behaviours of SCCM client and compare SCCM Client’s BITS setting against the above mentioned setting in local policy:

1. SCCM Client BITS setting left as default in SCCM (Not configured).

  • SCCM 2007 Client Computers: BITS policy in local GPO is set to DISABLED!
  • SCCM 2012 Client Computers: Same as SCCM 2007 client computers

2. Enable BITS in SCCM Computer Client Agent setting (In 2007, apply to both clients and BDPs, in 2012, just enable it since there is no BDPs in 2012 anymore.), and define some throttling settings. Then trigger machine policy retrieval on SCCM client computers.

  • SCCM 2007 Client Computers: BITS policy in local GPO is ENABLED in throttling settings are set to as same as SCCM policy.
  • SCCM 2012 Client Computers: Same as SCCM 2007 client computers

3. Change BITS throttling settings in SCCM. Then trigger machine policy retrieval on SCCM client computers

    • SCCM 2007 Client Computers: BITS policy in local GPO updated accordingly.
    • SCCM 2012 Client Computers: Same as SCCM 2007 client computers

4. Change BITS throttling settings in SCCM client’s Windows local policy. Then trigger machine policy retrieval on SCCM client computers.

    • SCCM 2007 Client Computers: local policy remained the same after machine policy retrieval.
    • SCCM 2012 Client Computers: Same as SCCM 2007 client computers

5. Change BITS throttling settings in SCCM again. Then trigger machine policy retrieval on SCCM client computers.

  • SCCM 2007 Client Computers: local policy was updated again according to SCCM client’s BITS policy.
  • SCCM 2012 Client Computers: Same as SCCM 2007 client computers


Based on the tests I have performed. I have come to below conclusions:

  1. When the SCCM client’s BITS policy is not configured, the  BITS throttling settings OS local policy is set to DISABLED, so effectively no BITS throttling is allowed for ALL the apps that uses BITS on the SCCM client computer. (i.e. in our case, VMM agent)
  2. Upon SCCM policy change, SCCM client changes local policy with updated settings once it has retrieved the updated policy via SCCM client’s machine policy retrieval (by default runs every 60 minutes).
  3. The SCCM client’s BITS settings are NOT enforced in local policy. i.e. when local policy is manually updated to be different than SCCM client’s policy, SCCM client does not enforce and update local policy. SCCM clients ONLY write to local policy when the SCCM BITS policy is CHANGED on the primary site.
  4. SCCM 2007 clients and SCCM 2012 clients exhibit same behaviour.

So, please look out if you have other apps that uses BITS and the bandwidth is throttled. SCCM client would update the local policy without you knowing it.

Alternatively, using a domain GPO to set BITS throttling settings seems like a good idea. By doing so, you can target different SCCM clients more granularly (targeting different OUs, using WMI filters and AD groups to set GPO scopes) whereas in SCCM 2007, this setting is unique across all clients in the primary site. Additionally, domain GPO will override local policy so local policy can be ignored.

Changing Display Language on Windows 7 Home and Professional Editions

Written by Tao Yang

I bought a laptop for other family members yesterday, it comes with Windows 7 Home Premium. I needed to change the display language from English to Chinese because the main user of this laptop does not speak English.

I thought it was a no brainer as I’ve done it before, all I had to do was to load another language pack in “Regional and Language” in Control Panel. However, I was wrong. apparently this function is available in Windows 7 Ultimate and Enterprise editions.

I didn’t really want to use Windows Anytime Upgrade to upgrade it to Ultimate just so I can change the language. Lucky I found this post:

So below is what I’ve done:

  1. Download Windows 7 Service Pack 1 language pack (Because the laptop comes with Windows 7 SP1, I had RTM version of the language pack but it didn’t work.) – I downloaded the entire ISO from my TechNet subscription, but there are many blog posts around with the direct link to Windows Update for each individual language (such as this one:
  2. Extracted the downloaded ISO (from TechNet subscription) to C:\Apps\langpacks
  3. in Command prompt:
    1. dism /online /add-package /packagepath:C:\Apps\langpacks\zh-cn\
    2. bcdedit /set {current} locale zh-cn
    3. bcdboot %WinDir% /l zh-cn
  4. Backed up and deleted HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\MUI\UILanguages\en-US
  5. Reboot

Note: if there were any windows updates that were pending to be installed, the install may fail after the language was changed. I had to run wuauclt /detectnow so Windows Update agent detects the updates for different language.

Failed to run PowerShell script via Task Scheduler on a 64 bit Windows

Written by Tao Yang

I came across a situation the other day that on a Windows Server 2008 R2 box, when I created a Scheduled Task to run a Powershell script, it runs OK using “C:\Windows\System32\WindowsPowerShell\v1.0\Powershell.exe” (64 bit PowerShell) but fails with error code (0x1) if I use “C:\Windows\SysWOW64\WindowsPowerShell\v1.0\Powershell.exe” (32 bit Powershell)

I have done the following steps to help me troubleshoot the issue.

1. I have changed the scheduled task to “Run only when user is logged on” so a command prompt was shown when the task runs. I screen captured the output:


It looks like the PowerShell Execution Policy is preventing the script to run.

2. I confirmed the execution policy setting is set to RemoteSigned – which is sufficient for the script to run.


3. However, when I launched “Windows PowerShell (x86)”, I got different setting!


4. I didn’t know that we can have different Execution Policy for 64 Bit and 32 Bit PowerShell:


5. So to fix the problem was fairly easy – Set Execution Policy to RemoteSigned on a 32 bit PowerShell console.

As we know that the PowerShell Execution Policy setting is stored in the registry  HKLM\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Micorosft.Powershell\ExecutionPolicy


The 32 bit setting is stored in another location: HKLM\SOFTWARE\Wow6432Node\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell


If the value “ExecutionPolicy” is missing, the default setting is “Restricted”. once I set the it to RemoteSigned, the ExecutionPolicy is created and set to RemoteSigned. If I delete it again, the execution policy is then changed back to “Restricted”

I don’t know what is the idea behind having 2 separate execution policies for 64 bit and 32 bit Powershell, maybe someone can share more information with us…

PowerShell: OS Build Script for Windows Server 2008, 2008 R2 and Windows 7

Written by Tao Yang


Around 2 years ago, I originally written a set of script to configure newly built Windows 2008 servers using PowerShell when my previous employer started to deploy their very first Windows 2008 server. These set of scripts were the very first scripts I’ve ever written in PowerShell.

Over the time, I have updated them many times and now they also support Windows 2008 R2 and Windows 7.

You can download the scripts HERE.


This set of build script is designed to automate the process of building a Windows server (version 2008 and above). It is designed for environments that do not have server SOEs. The intention is to install the OS with default settings and run these scripts right after the OS install. Although they will also work in Windows Vista and Windows 7, the settings are set according to server standard, they may not be suitable for configuring desktop / laptop for your end users.

Below is a list of items that these scripts will configure for you (and where you can set the values for these items):

Item Configured by Config-urable Configure from Note
Rename Computer 1_OSConfig.PS1 Yes User Input  
Registered Organization 1_OSConfig.PS1 Yes Configuration.ini (RegisteredOrg)  
Registered Owner 1_OSConfig.PS1 Yes Configuration.ini (RegisteredOwner)  
Startup & Recovery Options
Small Memory dump (256K)
Automatically Restart
Write an event to the system log
1_OSConfig.PS1 No    
Disabling unwanted services 1_OSConfig.PS1 Yes Configuration.ini (DisabledService) Enter the service name (not the display name) for each unwanted services
Enable Remote Desktop 1_OSConfig.PS1 No    
Screen Saver with Password Protection 1_OSConfig.PS1 No    
Screen Saver 1_OSConfig.PS1 Yes Configuration.ini (ScreenSaverName) Name of the screen Saver
Screen Saver time out 1_OSConfig.PS1 Yes Configuration.ini (ScreenSaverTimeout) Screen Saver Time out in seconds
Force Classic Start Menu 1_OSConfig.PS1 No    
Disable Windows Animations 1_OSConfig.PS1 No    
Automatically End Hung Applications on ShutDown 1_OSConfig.PS1 No    
My Computer Icon Matches System Name on desktop 1_OSConfig.PS1 No    
NTP Time source 1_OSConfig.PS1 Yes Configuration.ini (NTP) After joining to the domain, this setting will be ignored as the NTP setting is set to NT5DS
Disable User Account Control 1_OSConfig.PS1 No    
Boot menu time out setting 1_OSConfig.PS1 Yes Configuration.ini (BootTimeOut) Boot menu time out – in seconds
Power Options – High Performance 1_OSConfig.PS1 No    
Regional and Language Options 1_OSConfig.PS1 Yes Configuration.ini (UserLocale, SystemLocale, ShortDate)  
Configure Time Zone 1_OSConfig.PS1 Yes User Input  
Configure Network Connections
IP Address
Subnet Mask
Default Gateway
2_network.PS1 Yes User Input Inputs are validated
Rename Active Connections that have names start with “Local Area Connection” 2_network.PS1 No    
Configure DNS Servers 2_network.PS1 Yes Configuration.ini (DNSServer) Enter the DNS server IP address for each DNS server
Configure DNS Suffix Search List 2_network.PS1 Yes Configuration.ini (DNSSuffixSearch) Enter the domain name for each DNS suffix search
Disable LMHosts lookup 2_network.PS1 No    
Show Network Connection Icon in Sys Tray – Windows 6.0 (2008 & Vista) only 2_network.PS1 No    
Disable IPV6 2_network.PS1 No    
Rename Local Admin account 3_Security.PS1 Yes SecPolicy.inf (NewAdministratorName)  
Reset Local Admin Password 3_Security.PS1 Yes User Input + Configuration.ini (AdminPassword) User input to decide if the password needs to be changed. New password stored in configuration.ini
Rename Local Guest account 3_Security.PS1 Yes SecPolicy.inf (NewGuestName)  
Reset Local Guest Password 3_Security.PS1 Yes Configuration.ini (GuestPassword)  
Disable Local Guest account 3_Security.PS1 No    
Logon legal notice 3_Security.PS1 Yes SecPolicy.inf [Registry Values] LegalNoticeCaption and LegalNoticeText
Configure local security policy 3_Security.PS1 Yes SecPolicy.inf SecPolicy.inf will be applied to the computer. Log file: security.log
Configuring Event Logs (System, Application & Security) 3_Security.PS1 Yes SecPolicy.inf under [system log], [application log] and [security log] section
Configuring audit policies 3_Security.PS1 Yes SecPolicy.inf Under [Event Audit] section
Do not display last user name 3_Security.PS1 Yes SecPolicy.inf Under [Registry Values]
Configure LAN Manager authentication level 3_Security.PS1 Yes SecPolicy.inf Under [Registry Values], In Windows 2008 R2 and Windows 7, by default, it is set to only use NTLM V2. bu