Search This Blog

Saturday, 31 December 2016

Setting Windows regional settings, language and locale etc to en-GB in batch

The Problem

A load of PCs at my work have strangely been showing as having different regional formats even though the languages were set correctly. This was annoying as one of our in-house apps uses .Net date-time parsing which fails when the formats aren't correct. Instead of running up to each PC and manually clicking through forms, I wanted a scripted way (any would do, of forcing all related language settings on all versions of Windows (7 and up).

The Process

I made a batch script. Quick and cheezy.
Using control intl.cpl,,f:<filepath .xml="">you can make windows apply an XML file template. https://support.microsoft.com/en-gb/kb/2764405

I don't want to carry an XML file with the batch file... It just... Annoys me... Also, some of the settings require admin rights to take effect. So, one batch function for creating a temp XML file to be deleted after use and one function to check for admin rights.

The Code


@echo off
call:IsAdmin
set XMLPath="%~dp0en-GB.xml"
if exist %XMLPath% ( del /F /Q %XMLPath% )
call:CreateLocaleXML %XMLPath%
control intl.cpl,,/f:%XMLPath%
del /F /Q %XMLPath%
pause & exit
:CreateLocaleXML
echo ^<gs:GlobalizationServices xmlns:gs="urn:longhornGlobalizationUnattend"^> >> %1
echo ^<!-- user list --^> >> %1
echo ^<gs:UserList^> >> %1
echo ^<gs:User UserID="Current" CopySettingsToDefaultUserAcct="true" CopySettingsToSystemAcct="true"/^> >> %1
echo ^</gs:UserList^> >> %1
echo ^<gs:MUILanguagePreferences^> >> %1
echo ^<gs:MUILanguage Value="en-GB"/^> >> %1
echo ^<gs:MUIFallback Value="en-GB"/^> >> %1
echo ^</gs:MUILanguagePreferences^> >> %1
echo ^<!-- system locale --^> >> %1
echo ^<gs:SystemLocale Name="en-GB"/^> >> %1
echo ^<!-- input preferences --^> >> %1
echo ^<gs:InputPreferences^> >> %1
echo ^<gs:InputLanguageID Action="add" ID="0809:00000809"/^> >> %1
echo ^<gs:InputLanguageID Action="remove" ID="0409:00000409"/^> >> %1
echo ^</gs:InputPreferences^> >> %1
echo ^<!-- user locale --^> >> %1
echo ^<gs:UserLocale^> >> %1
echo ^<gs:Locale Name="en-GB" SetAsCurrent="true" ResetAllSettings="true"^> >> %1
echo ^</gs:Locale^> >> %1
echo ^</gs:UserLocale^> >> %1
echo ^</gs:GlobalizationServices^> >> %1
goto:eof
:IsAdmin
"%systemroot%\system32\reg.exe" query "HKU\S-1-5-19\Environment"
If Not %ERRORLEVEL% EQU 0 (
Cls & Echo You must have administrator rights to continue ...
Pause & Exit
)
Cls
goto:eof

Notes

In the batch function to create the XML file, I use the echo command and redirect the output to a file, but the '<' and '>' characters from XML are interpreted by the command processor as redirections. So I used the '^' character escape symbol.

I'm not sure if this works yet... Should do though.

Tuesday, 13 December 2016

Windows 8.x and 10 Update messing with net connections - Here's a Fix

Hi,
    I'll make this quick and not pretty. It's base simple but quite useful if you help your friends and family with IT stuff.

At the time of writing, it seems like Microsoft have released a dodgy update (which to my knowledge hasn't been identified yet). There's something about the DHCP client not retreiving the IP from the router/switch/AP side. I had a good friend at work send me a heads up on this while I was on the way into work today. When I got home, my laptop had lost LAN connection through Wifi.

http://www.theregister.co.uk/2016/12/13/microsoft_windows_10_broken_networking/

There are other sources, but that's a general overview. I read the article and adjusted the fixing lines of code into a simple to use batch script.

Note:This will require a restart of the PC
 - Copy and paste the lines below into a notepad window.
 - Save the text file and rename it 'fix.bat'.
 - Run as administrator:

@Echo Off
call :IsAdmin

echo Running "netsh winsock reset catalog" ...
netsh winsock reset catalog
echo Running "netsh int ipv4 reset reset.log" ...
netsh int ipv4 reset reset.log
Pause & Exit

:IsAdmin
%systemroot%\system32\Reg.exe query "HKU\S-1-5-19\Environment"
If Not %ERRORLEVEL% EQU 0 (
 Cls & Echo You must have administrator rights to continue ... 
 Pause & Exit
)
Cls
goto:eof

Thursday, 16 June 2016

WSUS Offline and Offline Servicing - How to download Windows Updates from your WSUS, not MS and apply them to your images

WSUS Offline

Many thanks to Torsten Wittrock and all the WSUS offline contributors for this FOSS package of scripts and tools. The open-source community can astound you with quality and flexibility in fields where commercial products leave a gap and this is a fine example.

Keeping offline Windows OS computers fully updated. Simple as:
1: Fire up the update generator on a PC with an internet connection
2: Select the updates needed for the offline computer and download
3: Move the folder to the offline computer by any storage medium
4: Fire up the update installer

The idea

If you know about how the Windows installation process works, you'll know that you can actually create customised installs of windows on various mediums, pre-loaded with drivers, updates, applications and enabled features accommodating some quite abstract deployment scenarios. When you're reinstalling PCs frequently, it's quite time consuming to 'clean' install from disk, then update, then add the extras, so the time invested in customising an image quickly returns several times over.

Strangely, even the customisation process has various methods and paths that do not necessarily have to be taken but can provide some advantages. You can take a PC, install it with all the business you need, generalise the Windows installation and capture an image of it to use for installation purposes. You can also use 'offline servicing' to take the install image from a Windows disc and apply your configuration options to it instead and I prefer this method for a few reasons. Firstly, I don't actually have to install the OS which would either require hardware or messing with VMs which takes space and CPU power, so more time consuming and the second is the process can be fairly automated so many bonuses to be had there as well.

The Problem

You can get most of the Windows versions ISOs for free which are easily mounted into a virtual CD drive or extracted to give you the installation files. These can be modified as described, but where do you get these packages? Drivers can usually be found on the manufacturer's web pages and discs, applications from their various sites, but what about the windows updates? Offline servicing is a helping hand, no doubt, but not a 'better' option, just a different method and at first, it would look as though an installation into a VM would be simpler, but this is where WSUS Offline comes in. You can download the updates, then apply them to the image using DISM (Great article, take note of updates to avoid).

Cool! But something's not working for me...

Excellent, I can use WSUS Offline to get all the updates for the various versions of Windows. Rock solid, and strangely enough, because I have VMs and a WSUS server, I wanted to see if I could get the updates from my server. I set the tools to point to my server, and it started downloading from Microsoft. This is the default behaviour, but I wanted my already vetted updates only, not all of them.

The solution

I added the line wsusonly=Enabled to the [Miscellaneous] section of the UpdateGenerator.ini file, but now the downloads kept failing because the download path was incorrect. My WSUS updates folder is called \WSUSContent\, but the path created by the tools pointed at \Content\. I knew the script to set this value had to be hidden somewhere in the folder so using a simple windows file content search, I found the line in the \wsusoffline\cmd\CreateDownloadTable.vbs file with the assignment: Private Const strWSUSRootFolder = "Content/". Change that to "WSUSContent/" and we're in business! Meanwhile, the answer was here, in German. :P

If you plan on creating customised installation media often, it may be possible to completely automate the tasks with scripts, but at least to myself, I have proved that it is possible to take a Windows installation image and add drivers, applications packages, enabled features and updates all with offline servicing.

Friday, 20 May 2016

PowerShell - Outputting PowerShell error text to log file

Seeing the red in black and white

The Idea

I'm trying to build an after-OS install deployment script that creates a log file when initiated and tracks the changes, successes and failures, during the deployment process, peeking back to see how far it's got so I can basically select from a defined set of configurations and leave the script to finish the job. The key requirements are that the script is highly compatible, so PowerShell v2 is the target. The script has to bypass common security dialogs for installers so the script is launched with the command PowerShell -ExecutionPolicy Bypass -File "%~dp0%thisScript%" and is lanuched as an administrator.

The Issue

The script output must be shown both in the command window and copied to a text file simply so I can see if anything went wrong without having to carefully examine the output of a command line window precariously left on a "press any key...", but can still see both the command line output in action in the window explaining where I am in the deployment process while the script is in action and check the log file at the end for error. Due to the fact that the script itself is designed to deploy various individual installers, it should record errors but not break on them unless critical. This can be handled through both capturing exit codes from installers and handling WMI queries in try catch code blocks.

I'm using command line to start the script and although I can redirect the output of the script launching command to a text file using something like:
PowerShell -ExecutionPolicy Bypass -File "%~dp0%thisScript%" > C:\Logs\ThisScript.txt
This would stop the console displaying the output of the script in the command window. The script would still run and be logged completely, but you wouldn't be able to see it processing the tasks.

I Did This

Being that PowerShell allows for "modules" (either scripts or compiled dlls), it seems logical to create a logging script module that I can throw objects down the pipeline which I can reuse in other scripts by calling the Import-Module cmdlet. This is a little complicated module and is still a work in progress.



Pretty nasty code alert:

[bool]$LogToFile = $False
$cDT = Get-Date
[string]$LogFilePath = ('{0}\Logs\ANOVO\{1}_ScriptLog.log' -f "$env:windir", ('{0}-{1:D2}-{2:D2}_{3:D2}-{4:D2}' -f $cDT.Year, $cDT.Month, $cDT.Day, $cDT.Hour, $cDT.Minute))
[bool]$EchoLog = $True
[bool]$LogMessagePassThru = $False

function Write-LogFile {
    param(
        [parameter(ValueFromPipeline=$True,
        HelpMessage='Enter message to write to log file.')][string]$logMessage,
        [parameter(Mandatory=$False,
        HelpMessage='Enter title for log file message.')][string]$logTitle = 'Log Entry',
        [parameter(Mandatory=$False,
        HelpMessage='Enter full path for log file.')][AllowEmptyString()][string]$logPath,
        [parameter(Mandatory=$False,
        HelpMessage='Allow pipeline message to pass through.')][bool]$logPassThru = $script:LogMessagePassThru
    )
    Begin {
    }
    Process {
        if($LogToFile)
        {
            if(($logPath -eq $null) -OR ($logPath.Length -lt 1)) { $logPath = $script:LogFilePath }

            if(!(Test-Path (Split-Path -Parent $logPath))) {
                New-Item -ItemType Directory -Force -Path (Split-Path -Parent $logPath) | Write-LogFile -logTitle 'Logs Directory Created' -logPath $logPath -logPassThru $False
            }
            if(!(Test-Path $logPath)){
                New-Item -ItemType File -Force -Path $logPath | Write-LogFile -logTitle 'Log File Created' -logPath $logPath -logPassThru $False
            }

            ('[{0} - {1}] {2}: {3}' -f (Get-Date).ToShortDateString(), (Get-Date).ToLongTimeString(), $logTitle, $logMessage) | Out-File $logPath -Append -Force
        }

        if($logPassThru) { $logMessage }
        else
        {
            if($EchoLog)
            {
                ('[{0} - {1}] {2}: {3}' -f (Get-Date).ToShortDateString(), (Get-Date).ToLongTimeString(), $logTitle, $logMessage) | Out-Host
            }
        }
    }
    End{
    }
}

Export-ModuleMember -Function Write-LogFile

Export-ModuleMember -Variable LogFilePath
Export-ModuleMember -Variable LogToFile
Export-ModuleMember -Variable EchoLog
Export-ModuleMember -Variable LogPassThru

The Problem

The key issue I wanted to resolve was how to get the PowerShell red failure text to copy to the log file. It's actually quite readable and if nothing more, reports the point of failure the script quite noticeably when reading through a large log file. Also, I needed to have the text captured on commands and installers that may fail. Errors in PowerShell can come from multiple angles (installers, powershell commands, WMI object functions and more) and handling these isn't uniform. Sometimes, a function call may fail, but not output an error or may completely fail and stop the script.

My Solution

I set up a quick check using the $? operator, $Error[] array and catching the last output.

Write-LogFile "Beginning function..."
Preform some object function that may fail but not report it here
if($?)
{
  Write-LogFile 'This was successful.'
}
else
{
   Write-LogFile "This was not: $Error[0]"
} And...

Write-LogFile "Something may break here..."
try
{
  Preform something that could cause powershell to red text
}
catch
{
  Write-LogFile 'You broke it!'
  Write-LogFile 'Powershell Error Message:'
  Write-LogFile $_
}
When we do this, the full error text shows up in both the command line window and in the log file, allowing the script to continue. If you don't wan to capture the fully qualified error, you can just caputre the general message with $Error[0].Exception.Message




Code and output:
PS C:\>
try
{
  MakingSomething-Up
  Write-Output 'Successfull.'
}
catch
{
  # $thisError = $Error[0].Exception.Message
  Write-Output 'Failed.'
  Write-Output 'Powershell Error Message:'
  Write-Output $_
}

Write-Output 'Reached this too...'
Failed.
Powershell Error Message:
MakingSomething-Up : The term 'MakingSomething-Up' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a
path was included, verify that the path is correct and try again.
At line:4 char:3
+   MakingSomething-Up
+   ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (MakingSomething-Up:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Reached this too...

PS C:\>

Thursday, 19 May 2016

dotNet File Hash - Work in Progress

dotNet File Hash

Why?

I was dissatisfied with a lot of "duplicate finder" applications showing various inconsistencies from being too accepting ("This picture, kind of looks like that one") or too unforgiving ("This file has a different creation date so it must be different"). The key functionality I was looking for is file content comparison without taking into account additional extended data applied by filesystem or OS. File hashing seemed like the most logical course, and, thanks to Google and the open source community, there were many good examples for me to get started from...

What?

This is a C# .Net 4.0 file hashing Windows application that implements a variety of hashing algorithms (MD5, SHA1, SHA256, SHA384, SHA512, RIPEMD160) readily available in the System.Security.Cryptography section of the .Net framework and can be used to compare files from various folders for true file duplications by directly hashing the content and ignoring other extended details.

I've started to add extra stuff like saving of hash lists and some light theming (check preferences), but this application is not finished and should be considered "alpha" software. At the moment, due to the way I calculate duplicates (MD5+SHA1), there is a mathematically ridiculously small probability of a false duplicate (Birthday Paradox and whatnot) so check your selection before deleting (not implemented yet) anything. As always, use this at your own risk, but if you feel unsure, read through the code.
 
The application UI is pretty crude, but the underlying code is quite lean. As always, this application is an example project for other users to take the code from and use as they please according to the GNU GPL V3 license referenced within the application.

License

GNU GPL V3

Requirements

OS: Windows XP or betterMicrosoft .Net framework v 4.0 or better

Main Window

 

 Preferences

 

Duplicate Highlighting - Hide Unique


Show Only Duplicates

 

File Grouping and Duplicate Count for group

 

Project Page

https://sourceforge.net/projects/dotnet-file-hash/

Wednesday, 18 May 2016

Stranded 2 Mod Viewer - My addition to an awesome if aged game

Stranded II Mod Viewer

Why?

When I was growing, a fantastic step in understanding various 3D modelling file formats came in the form of an open source first person shooter survival and crafting game that stole my heart for its simplicity yet versatility. This was Stranded 2. I played this game for months before the sheer difficulty of trying to discover undocumented functions led me to joining the forum and found that much of the game is deliberately undocumented. Not only that, the game allows for large scale modifications of the game via rescripting of the game files that are simple text files but in a new and interesting way. This meant that there were many mods of the game which greatly expanded on the original experience and were worthwhile playing that still suffered from the same lack of documentation and held me back in the original. So I started working on a solution.

Originally, I just wanted to create something to tell me what items I needed to combine to get better items without asking on the forum or trawling through stale text files...

What?

With the help of DC, the game creator and Builder, the creator of "Massive Mod", I have created an application that reads the game files of most mods (dependant on both complexity and poor scripting). It can detect and inform of some basic errors in the game files, helping modders refine their mods. It also gives an informative display of the items, objects, buildings, combinations and units so new players might find this useful as a guiding tool. I've also included intuitive controls for navigating around different pages and objects,  custom columns with item count, ID, effects and more are displayed in a simplistic and easy to read way.

License

GNU GPL V3

Requirements

OS: Windows XP or betterMicrosoft .Net framework v 4.0 or better

Items View

Combinations View

 

Buildings View


Project Page

https://sourceforge.net/projects/stranded-ii-mod-viewer/

Tuesday, 17 May 2016

PsyPlay - My FOSS C# Media Player using Direct X as a display interface

PsyPlay

Why?

I was getting into Windows forms programming in C# (.Net 3.5) and was interested in how I could make a simplistic media player that operated with the system installed codecs for media. Straight up, I'm not good enough to import and start handling loads of different FOSS codecs; I can barely program, but I thought that it had to be possible, so with a little bit of Googling DirectX C# implementations, I started a basic window... It kind of grew from that...


What?

It's a bare simple media player with a laughable amount of "theming" capabilities but it functions, has some cool options like real file drag and drop into other applications (warning, this can move files), a media library function, video capabilities with full screen, keyboard controls etc. More than anything, this is an example project I made years ago to demonstrate DirectX in C# which is probably fairly outdated now, but due to .Net compatibility, may be relevant to some.

 

License

GNU GPL v3

Requirements

OS: Windows XP or better
Microsoft .Net 3.5 Framework (up to 3.5.1)

Main Player

 

Video

 

Media Library

 

Project Page

https://sourceforge.net/projects/psyplay/

Monday, 16 May 2016

ISESteroids - Exhaling from the complication of PowerShell version control

ISESteroids

How I found...

Backstory - Tl;Dr - I stumbled into coding

For the purpose of this article, I would describe myself as a power user with added Google, not a programmer, technician or any other title that would insinuate I have had any form of structured training in creating programmatic solutions. I'm just a guy who grew up in PCs; playing with them, fixing them, sleeping on them. I am by no means methodical in my programming and scripting. I approach new languages by having a goal in mind and acquire only the necessary information to achieve this, which gives some bare understanding but always a poor foundation that eventually becomes more established as the use of the language becomes more required. It's a bad way of learning for various reasons, but I find it allows you to easily change your understanding of the language in an instant. So I can barely read ASM, barely code in C, code console applications in C++ and can program various windows applications in C#. There's some batch scripting in there, VBscript and now PowerShell.

The main thing I learned from this is that most goals are achiveable by using any of the languages, but the caveats of each method and language make them particularly well suited to one type of task or another. You can have developers toss around jargon about who's language is better but languages aren't created for fun (well, yes but no). Lots of people have spent a long time making a defined language, getting it established and giving it relevance. They're created with intent and that makes them tuned. Knowing which one suits your purpose is half the battle.

The Project - Help People

I help people with PCs. Possibly out of a sense of duty, probably out of ego, definitely with one intent; Make the user more comfortable. Not just content, but with a sense of security. This is why I back up Windows installations and advise personal data be stored on other medium than your operating system disk. Still, this does not prevent people laying waste to their OS and possibly the disk. Although there are a few recovery techniques available to recover even the severest of data loss, there is no guarantee that any method will work and usually results in a full reinstallation of the OS and associated applications anyway. The faster you can make this happen, the generally more comfortable people are.

Whenever I find myself repeating anything in computing, there's probably a way to automate it, and in this case, the method is clearly scripting. Creating a program to do the install of multiple applications and system setting configurations can be done, but due to the simplicity of editing, the ease of flexibility and the general ability to handle various types of installers with their own quirks, scripts work for me.

PowerShell, how your versions aggrivate me so

Batch was the boy back in the day when I was a boy for handling Windows OS and even today, due to the sheer simplicity, lots of IT professionals rely on batch scripts, usually and ironically to launch other types of scripts (I use a batch to start a PowerShell script). The the age old and still thriving start of my scripting life has evolved through various new implementations for greater system control (VBScript) and updated with a greatly expanded set of system interfaces (PowerShell). I love the greater flexibility in controlling the all aspects of the operating system and the language is strangely asthetically pleasing, but now I find myself knee deep in the "pipeline" getting pounded by unknown object types. Microsoft have provided a good integrated scripting environment (ISE) for PowerShell, but jeez, it's bare.

 

Steroids?? Ok...

This is the 4th iteration of PowerShell I'm using  and it still feels a bit lacklustre. The bare essentials are there for a scripting environment; coloured highlighting and intellisense (auto-complete :P) but still, in terms of error checking and debugging, you're usually on your own. This can leave you resorting to trial and error of scripts and entering commands every time you need to pull up help or running tandem with a browser. Some of these are more serious than others but the straw that made me seek a better alternative was version control. How could I tell if my scripts would run on a PC with only PowerShell v2, or if other apps are called in? The time and effort it would take to research the compatibility of every command in my scripts and modules could take me a lifetime, or at least feel like it, so I looked for something that could provide the most needed aspect... Luckily, it came with much more. Enter ISESteroids.


Getting Started With ISESteroids

Installing

This was slick. If you have PowerShell v5, you can just open the normal ISE and type some commands (available on their downloads page). As I'm poorer, I got the download package.

It was a case of unzip, click install.bat, start the ISE and type "Start-Steroids"... And thats it...

Can't fault it for simplicity and there are instructions on how to make it load with the ISE, but that choice is up to you. I like having the option to step up to for full editing and bare ISE for quick typos (What? They happen...).

The UI

It gave me a wonderfully warm reminder of the time as it began initialising.
 

Then the UI with an array of new buttons.


Jumping straight in

Immeditately, it felt like what I was hoping for. A familiar interface with more control. So I loaded a script and opened the new "Context Sensitive Help Add-On" which I was excited to read about on their reviews. This wonderful little thing grabs relevant help to whatever is selected in the scripting window.
 

The squiggly line shows me where an error exists or simply better writing could be used. That was particularly useful in scripts where I'd used the "Where" alias everywhere, wheras a more compatible "Where-Object" would be better. So when I selected and hovered over the squiggly line under a string I'd written in this script, the side bar displayed information about what I selected and the popup told me that using single quotes would be better practice. Very cool for my learning curve. Even better, if you follow the line with the correction to the left edge, there's a lightbulb icon that, when clicked, will correct all this type of correction in the entire script.

 

So with automatic script fixes and real-time context sensitive help, I can see the value in this. After making the correction, the help panel updated.

 

Solving the problem

The main reason I'd got this was to see if something very important worked. This was version checking. In my version, this was in the "Compatibility" section of the main menu strip.

 

It was only then that I also stumbled across the "Create Compatibility Report" function which does exactly as it says, giving a list of all the dependancies your script has to outside objects such as other modules, executables and more. The only thing that came back on mine was references to my other modules.

 

Summary

There's no doubt that this software has some real power under the hood, adding so much that I haven't mentioned and resolving a lot of the pet hates I had when working with PowerShell. If you're working with PowerShell intensively, either as a hobbyist or a professional, I would advise at least taking the free 10-day trial just to see what it can do for you. ISESteroids has helped me correct and refine much of my poor scripting, it's gonna be hard to go back to anything else.

Nice work, problem solved.