Thursday, 4 April 2013

Migrating Wireless settings between Windows 7/8 Machines

 

I have recently been given a new laptop from work, as part of the setup process I needed to copy over the large number of wireless networks that I connect to as part of my job.Windows provides an export using the netsh command

netsh wlan export profile folder=. key=clear

The code above will export all networks as individual xml files into the current working directory which is great, however the netsh command does not to my knowledge allow the import of all definition files in a directory in one go, so how to solve this problem? Our old friend PowerShell, after all we are batching a command and PowerShell is pretty good at not giving a damn about file names or how many items are in a folder.

 

So this post is going to be all about a PowerShell script which allows you to export your wireless settings and import them again elsewhere. The script itself is split into several functions and a few loops and is pretty simple and can probably be made much more elegant, however it does work Smile

 

Code:

We start by declaring or resetting our variables, always a good idea if we are running the code in the PowerShell ISE or PowerGui (My preference) in case any values remain from a previous run through

1 $path="D:\Wireless"
2 $menuanswer=$null
3 $pathready=$null

$path is the path we want to use to store the wireless xml files in, this can be edited to any folder we like (useful if you don’t have a d: drive like I do)


Now we need a few functions, the first will export our wireless connections to xml files


Export Profiles


1 function export_wifi_profiles{
2 #check for folder path
3 $pathready = Test-Path $path
4 if ($pathready -eq $false){
5 mkdir $path
6 }
7 cd $path
8 netsh wlan export profile folder=. key=clear
9 }

Line 3 is used to check whether the path we have specified earlier as available, if the path does not exist then the folder specified will be created before moving on, if it exists then the netsh command will be run which will dump all wireless networks as individual files into the path.


 


Import WIFI Profiles



1 function import_wifi_profiles{
2 #check default path, if not found prompt for location
3 do {
4 $pathready = Test-Path $path
5 if ($pathready -eq $false){
6 $path=Read-Host "Default import path not found, please enter the path your profiles are stored in"
7 }
8 } until ($pathready -eq $true)
9
10 $path | Get-ChildItem | ForEach-Object{
11 $filepath=$_.FullName
12 netsh wlan add profile filename=$filepath user=all
13 }
14 }


As with the export this function checks for the existence of the folder stated in the $path variable, if it does not exist then the user is prompted to enter the path to their network profiles, once a valid file path is provided the script collects all of the items found within (Get-ChildItem), it then copies the full file path and name into the $filepath variable, this is then used in the netsh command to do the actual import of the wireless profile.


The beauty of the Get-ChildItem | ForEach-Object code is that it doesn’t care whether you have 1 or 100 wireless profiles in the folder, it will work its way through each of them until it is done.


 


Create a Menu


1 function menu{
2 cls
3 Write-Host "1 Export Wireless Profiles"
4 Write-Host
5 Write-Host "2 Import Wireless Profiles"
6 Write-Host
7 Write-Host "0 Exit"
8 Write-Host
9 $menuanswer=Read-Host "Please make Your selection"
10 if ($menuanswer -eq 1){export_wifi_profiles}
11 if ($menuanswer -eq 2){import_wifi_profiles}
12 if ($menuanswer -eq 0){exit}
13 }

The code above create a simple menu with options 1,2 and 0 to exit, the users entry is saved into the $menuanswer variable and evaluated against the options in lines 10,11, and 12, if the entry matches any of the options then that function is called, the {exit} command will terminate the script and completely exit PowerShell.


 


Call the Menu until exit command used (0 Key)


1 do {menu} until ($menuanswer -eq 0)

This code will simply repeat the Menu function until the user enters 0, this allows the user to export and re-import the wireless profiles for testing purposes if that is required. It is the only real line of code which is run when you launch the script, the functions are called as needed.


 


Putting it all together


 


Copy and paste the contents of the next box and edit the $path variable at line 2 to suit your own needs, as I have said this is a basic script and can be made much more elegant but for my needs it was suitable, good luck.



1 #declare variables
2 $path="D:\Wireless"
3 $menuanswer=$null
4 $pathready=$null
5
6 #Declare functions
7 function export_wifi_profiles{
8 #check for folder path
9 $pathready = Test-Path $path
10 if ($pathready -eq $false){
11 mkdir $path
12 }
13 cd $path
14 netsh wlan export profile folder=. key=clear
15 }
16
17 function import_wifi_profiles{
18 #check default path, if not found prompt for location
19 do {
20 $pathready = Test-Path $path
21 if ($pathready -eq $false){
22 $path=Read-Host "Default import path not found, please enter the path your profiles are stored in"
23 }
24 } until ($pathready -eq $true)
25 $path | Get-ChildItem | ForEach-Object{
26 $filepath=$_.FullName
27 netsh wlan add profile filename=$filepath user=all
28 }
29 }
30
31 function menu{
32 cls
33 Write-Host "1 Export Wireless Profiles"
34 Write-Host
35 Write-Host "2 Import Wireless Profiles"
36 Write-Host
37 Write-Host "0 Exit"
38 Write-Host
39 $menuanswer=Read-Host "Please make Your selection"
40 if ($menuanswer -eq 1){export_wifi_profiles}
41 if ($menuanswer -eq 2){import_wifi_profiles}
42 if ($menuanswer -eq 0){exit}
43 }
44 #End Functions
45
46 #Begin main Program Block
47 do {menu} until ($menuanswer -eq 0)
48 #End main program block

Monday, 25 February 2013

MDT Naming Trick - Show Machine's Existing Name

MDT Pre-Populate Name Trick

You ever had it when a machine needs to be rebuilt because it's either crashed completely or is suffering issues that you know, deep down in your technical heart, a rebuild will sort it all out.

So what do you do?

You press that magical network boot key, PXE boot that machine and start the MDT process.  Fantastic, you the go through the wizards to eventually get to the "Computer Name" stage where it then prepopulates the name with a MiniNT name and you go.. hmm.. bugger what the name of the machine again?

You look for a sticker, which has obviously fallen off or worn away, you think i'll need to reboot to get to the login screen to find the name there.. which isn't an option if the machine is totally broke.

Wouldn't it be nice to have the machine put in its actual, existing name in place of that MiniNT name, still editable if required, but there for a reference at least.  Well you can, using some minor trickery and awesomeness.

Thanks to Michael Klinteberg from Technet forums, a simple script copied into the Scripts folder in your deploymentshare and two lines added to your customsettings.ini file will give you the desired effect.

Copy the below script into notepad and save it as "UserExit.vbs"





Function UserExit(sType, sWhen, sDetail, bSkip)
 oLogging.CreateEntry "entered UserExit ", LogTypeInfo
 UserExit = Success
End Function

Function GetOfflineComputername()
On Error Goto 0

 If oEnvironment.Item("OSVERSION")="WinPE" Then
  Dim CompName : CompName = ""
  Dim ret, sOldSystem : sOldSystem = ""
  For Each drv In Array("C", "D", "E", "F")
   If ofso.FileExists(drv & ":\windows\system32\config\system") Then
    sOldSystem = drv & ":\windows\system32\config\system"
    Exit For
   End If
  Next
  oLogging.CreateEntry "Mounting Offline registry " & sOldSystem, LogTypeInfo
  ret = oShell.Run ("reg load HKLM\z " & sOldSystem, 0, True)
  If ret = 0 Then
   CompName = oShell.RegRead("HKLM\z\ControlSet001\Services\Tcpip\Parameters\Hostname")
   If CompName <> "" Then
    oLogging.CreateEntry "Found old computername '" & CompName & "'", LogTypeInfo
   Else
    oLogging.CreateEntry "Old computername name could not be found", LogTypeWarning
   End If
  Else
   oLogging.CreateEntry "Could not mount offline registry " & sOldSystem, LogTypeWarning
  End If
  oShell.Run "REG UNLOAD HKLM\Z", 0, True  
 Else
  CompName = oShell.ExpandEnvironmentStrings("%Computername%")
 End If

 GetOfflineComputername = CStr(CompName)
  
End Function


Tuesday, 25 September 2012

No Policies Applying, Temporary Login, Windows 7

No Policies Applying, Temporary Login, Windows 7 x64/x86

You have been logged in with a temporary profile..  even though the user in Active Directory (AD) is setup correctly and the NTFS/Share permissions are also.. setup correctly.

Whats going on? Hopefully this post will help.

Applies to: Windows 7 x86/x64, Windows 2008R2 Domain

Symptoms

  • No Group Policies have applied to the profile
  • No Mapped Drives/Printers
  • No Preferences Applying
  • Admin (like) control of the machine, no restrictions set
  • An explanation mark (!) in a blue circle appears in the system tray
  • A balloon appears/tries to appear notifying the user that they are logged in with a temporary profile
  • The login is way too quick.
  • If you log out and log back in sometimes the profile works fine, sometimes it logs back in again as a temporary profile. 
  • The issue is intermittent with little/no pattern, sometimes does it, sometimes it does not. Not machine specific, not user specific.
  • If you wait for a few seconds before logging in, the chances of the profile working correctly improves.
  • Occurs more often on wireless devices than wired, but isn't limited to wireless.



Reasons

When Windows 7 was the new big thing, Microsoft had a page about all the cool new features of their brand new operating system.  There was one feature (which unfortunately I have forgotten the name of) but it boasted about priority, fast logins.  Essentially, it meant that if Windows 7 noticed there would be a delay in the logging in, it chose to prioritise just getting the user to the desktop rather than waiting to ensure the login was correctly done.

This is what you are encountering.  Some networks, particularily wireless ones take that little bit longer to establish a new IP address, down to poor signal strength or just generally the type of wireless card you have in your device.

So when a typical user, types in their username and password within seconds of the machine first booting, the chances are the computer hasn't yet got an IP address or stable connection with the server but still attempts to log them in regardless.  Windows 7, realising that there is a networking issue, rather than saying to the user, "Please wait a sec, I haven't fully established a trust with the server", it simply goes, "oh who needs a server, I know your credentials are correct, thats all I basically need, heres a desktop", perfect if you are a home user, really annoying if they are domain user.

Resolutions

Nice and Easy, theres a group policy for it.  Inside that needle in a haystack database there is a policy that ensures the computer (regardless of whether its wireless or not) will make sure the user will not be able to login until a stable connection is first established.

Located Here

Windows Server 2008R2
Computer Configuration -- Policies -- Administrative Templates -- System --  Logon

Windows Server 2003R2
Computer Configuration -- Administrative Templates -- System -- Logon

Policy Name

Always Wait For The Network At Computer Startup And Logon

Set to: Enable



How it works

This is a brilliant policy when applied as it ensures that when a computer is loading up and a user attempts to login the second they can type, it overrides the client operating system's decision to prioritise getting the user to the desktop. 

All policies will therefore come down to the client and apply to the user and computer, thus ensuring that their logins are correctly redirected and their resources (shared areas and Printers) are correctly applied in accordence to your ICT policy.



I hope this helps you all out, I understand that Windows 8 is out soon but for those looking to upgrade to Windows 7, this is a small bug i'm sure you will come across.

It is easy to ignore when testing as when it happens you log off and you log back in and it all seems fine, but bear in mind, you are a technician, you use computers in the way they should be used.  True testing comes from the end user and not the ICT department.

I'm happy to help out anyone with any more issues in relation to this, just leave a comment below.  Additionally, any other fancy features you may of found in the GPO Needle in a haystack database, which you feel will help optimise Windows 7's logging in speed and/or reliability, never hesitate to post a comment, we are all on the same team here, all help is much appreciated.

Speak to you all soon,

The ITMagician

Monday, 17 September 2012

Restart Pending? But I've restarted!

Cannot start/begin installation due to restart Pending on your machine.

Applies to Windows Vista, 7, Server 2008, Server 2008R2

This is an annoying issue.  You've recently uninstalled something or you've just updated the machine with the most recent windows updates, whatever the reason, you cannot install something because apparently, even after several restarts, the computer still wants a restart..

Nice and simple (and you don't even need to do another restart). 

Go to Run, type Regedit.

Go to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager

Look for the key PendingFileRenameOperations

Right Click and edit.

See that list of random stuff in there, that's the stuff that is stuck "pending for install" and fails to remove itself once you have.

Highlight it all, Delete.

Press Ok and leave the registry.

Now, restart your software install.  Hopefully, fingers crossed, you should be pleasantly surprised that you can now start your installation successfully.

Keywords
Exchange 2007, 2010
System Center
DPM Data Protection Manager
SCCM System Center Configuration Manager
SQL Server 2008 R2, 2012
                     

Monday, 20 August 2012

Windows 8 ADK (The new WAIK)

Yes folks, Microsoft have updated their tools for working with windows images.

What was once known as the Windows Automated Installation Kit has now been merged with more utils and is now called the Assesment and Deployment Kit.

A quick look on Microsofts site only seems to proveide a bootloader to install from the internet however if you run this file you are presented with the option to download the files for offline installation.

Be warned though its a biggie coming in at around 3 and a bit Gig.

It can be downloaded from here

Wednesday, 1 August 2012

Creating a more useful Powershell prompt

 

 

As Microsoft are moving more and more functions for their products to be Powershell aware, we are starting to use PS more than VBScript in our daily lives. Although I often use Quest’s Powergui for my coding as the watches built into the interface make debugging easier, I do also make use of the Powershell itself, in these instances I have to import the relevant module manually, by editing your PS profile you can make these tools available every time you click on the little blue icon.  This walkthrough will install the Active Directory and Exchange tools.

 

Here are the steps to achieve this.

 

1. Create a profile (If you don’t already have one)

New-Item -Itemtype file -path $profile -force


2. Edit your profile with notepad

notepad $profile

3. Add the following code

import-module activedirectory

Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010
. $env:ExchangeInstallPath\bin\RemoteExchange.ps1
Connect-ExchangeServer –auto

4. Save the file and re-open Powershell

 

You will now have a Powershell which loads the AD and Exchange tools by default.

Sunday, 29 July 2012

WMI Filters for Windows Operating Systems

For those of you wanting to filter your GPO's by OS here are the filters we use. The filter works against the root\CIMV2 namespace


Windows 8

Select * from Win32_OperatingSystem Where Version like "6.2%" and ProductType = "1"


Windows 7

Select * from Win32_OperatingSystem Where Version like "6.1%" and ProductType = "1"

Windows XP

Select * from Win32_OperatingSystem Where Version like "5.1%" and ProductType = "1"