Showing posts with label scripts. Show all posts
Showing posts with label scripts. Show all posts

Friday, July 20, 2018

My Book Scripts

I saw a comment over on Amazon relating to my last PowerShell book (see Amazon Book Listing) from Long Time Programmer. His comment is that he couldn’t download the code. I wish there was a way I could comment on his comment as there is a way. I’ve put all my scripts up on GitHub!  If you go to https://github.com/doctordns/PowerShellCookbook you can see the scripts there.  Although I have to say some of them – getting the scripts onto GitHub is a work in progress.

As an aside and for background: the publication process at the time this book was published had a few issues.  The web site used to enter content  was literally eating content so we switched over to word at last hour. In doing so, the longer-line scripts ended up broken in the final PDF and thus the published version.

To be helpful to my readers, I’ve slowly retrieved the scripts from inside the VMs and have published them to GitHub, Which is less simple than it sounds and it not yet complete. At present, I’ve ported over the recipe scripts for chapters 1-4, 8, 10, 11 (7 out  of 13). And I hope to have the updates soon.
Please download any of the scripts – and file issues if you find problems.

[Later]
The conversion has been completed and I've created a version 1.0 of the scripts on the GitHub repository. . You can consume the scripts by navigating the GitHub UI or you can take a fork and clone to a local machine. The release mechanism in GitHub provides a zipped up Go to the GitHub Release page and download a .gz or .zip file depending on your tastes. I may do some further tidying up. 

Monday, February 04, 2013

Building A Hyper-V Test Lab on Windows 8 – Part 5 Configuring DC1

Introduction

This the fifth part in a multi-part set of articles on building a test lab with Hyper-V and PowerShell. See the following prior articles in this series.

Configuring the First DC

In the last article, I showed you how to create a domain controller in a new forest by taking a newly installed workgroup server and promoting it to be the first domain controller in a new domain/forest.  Since the DC provides the AD environment for the rest of the VMs in my test lab(s), it has to become the DC before any other VMs are created. Once the server becomes the domain controller, a second script is used to configure the DC. Note that most of the other servers can be configured in just one step (although the jury’s still out that with respect to Lync and Exchange).

In this article I present a second configuration script for the domain controller, snappily named Configure-DC1-2.ps1. This second script just finishes off the configuration and setup of the DC. Once the DC1 VM has been created and promoted to being a domain controller, you use this second script to finish configuration.

From a work flow perspective, once the DC has been created, creating and configuring other new VMs can be done in parallel with configuring DC1 (i.e. running Configure-DC1-2). Also, if you are creating VMs that rely on DHCP, you would need to complete the DCHP configuration before those VMs are created.

In my lab’s case, configuration the first domain controller, DC1, is pretty simple:

  • Set the VM to automatically logon as the domain admin – in lab environments, life really is too short to have to type credentials any more than is absolutely needed. So I set the registry settings to enable auto admin logon
  • Install Key Windows features - I include some simple features, including IIS (which is needed to enable the DC to be a CA).
  • Install and configure basic DHCP - Most of my lab machines have fixed IP addresses, but having a small DHCP block seems a good thing! I allocate 20 IP addresses, but you could change that as needed. I also configure this scope with some basic options (IP, subnet mask, and DNS Server). You could add a default gateway if you want to enable routing via the host.
  • Create a second administrator – I create one extra user, me (TFL), and add this user to domain and enterprise admin groups. I have a further script Configure-ReskitAD.ps1, as part of this series, that adds a richer AD environment in terms of a coupe of OUs, and more users.

Once that has been done, I do two more things in the script (outside the configuration block):

  • Force a reboot of the VM – The very last thing the script block does before returning is to call restart-computer. The reboot is, in effect, asynchronous. Thus after the script exits and control is passed to the main script running on the Hyper-V box which continues while the DC reboots. After the exit, the script restarts DC1.
  • Take a snapshot of the DC. This is useful if I want to do some AD configuration but then back out of that. To cater for the async nature of the reboot (it happens in another process/VM), I use the the parameters ‘–Wait –For PowerShell’ which waits till the system has rebooted, the user has logged on before proceeding to take the actual snapshot. .

Using Remoting to Configure DC1

In the first two scripts that create and start up the VM, the scripts contain a function definition that is then run against the local system, i.e. the host you are using to run Hyper-V. In my case, this was done on Windows 8 on my laptop and one of my Server 2012 boxes. They both run Hyper-V well so testing is easy both at home and on the road. As I noted previously, the remainder of the scripts I use that to setup and configure the domain and servers use remoting. The following pattern if these scripts is as follows:

  • Create a script block, $CONF or similar, containing PowerShell code to perform some configuration on a server. The PowerShell code is intended to run in the target VM.
  • Use Invoke-Command, and the appropriate credentials, to run that script block on a remote server (i.e. one of the Hyper-V VMs you are building/configuring.

This process is flexible and allows me to do things before invoking the script block. For example, to install SQL, Exchange or Lync, I need to have the product CD inserted in the D: drive. For Exchange, I have to load some pre-requisites onto the server, for example bits of IIS, etc. that are not needed for other labs. SO in that case, the configuration script file can create a couple of script blocks to divide up the work. In the longer term I consolidate the multiple script blocks, but that’s work to be done!

Snapshotting VMs

These scripts were designed to support me in writing and developing courseware. Since the development work can be error-prone plus with a need to test, test, and re-test lab instructions, I need to take snapshots before and after key configuration events. So what this script does, at the very end, is to take a VM snapshot and label it as being created by this script. You can, of course, comment out this if you don’t need to have a snapshot!

Using the Scripts

When I am building out a new set of VMs, I open ALL these scripts in the ISE on the Hyper-V host. Whilst I am at home, that means running these via a terminal services window against one of my Hyper-V servers or my laptop. Once I have all the scripts open, I just work through them, tweaking the unattend.xml, building the base disk, building then promoting DC1, finishing off DC1 configuration, configuring a CA, configuring the IIS servers, etc.

Getting the Scripts

I have published the full set of deployment scripts to my web site, at http://www.reskit.net/powershell/vmbuild.zip. Note that some of the scripts in this zip file are very much works in progress that are changing, and hopefully improving, as I publish these articles. I reserve the right to change any of all of them from time to time. I will try to blog any important changes.

I am also publishing the individual scripts over on my PowerShell Scripts Blog:

Recent Script Changes

Since starting this series, I’ve been tidying up the scripts. In some cases, I’ve moved parameters into hash tables to increase readability. The changes to the scripts are now added to the script itself. One key change is that I set Auto-Admin logon for all servers, and force a reboot of the server after configuring it. I’ve also added some judicious Hyper-V check pointing into some of the scripts to simplify both further testing and to suit my courses.

[Later]

In the original post, the reboot and snapshot were not handled in a tidy fashion. I re-coded this logic so that the configuration script block does NOT do the restart. Instead, I let the script block continue, and exit back to the main Configure-DC1-2 script block where I then forcibly reboot the DC, wait till the reboot has completed then take the snapshot. Just a little more elegant and it ensures that the snapshot after the reboot has completed and the auto-admin logon has occurred. This makes reverting back to the snapshot that bit easier.

Future Scripts

The next couple of scripts, which I hope to get documented this week, including building and configuring general purpose servers and creating a Certificate Authority. I also have some utility scripts that I have added and will also be documenting.

Comments

Any comments? I’d love to hear from you – either as comments to this blog post, or via email.

 

Friday, June 03, 2011

Spell Checking Strings in PowerShell scripts

Let’s face it – spelling misteaks suck. Whether in a blog post or in a PowerShell script. Doug Finke has written a nice article on this subject that shows  how to spell your strings in your scripts. He even includes a script to do it! You can Download the PowerShell script  HERE.

Technorati Tags: ,,

Thursday, June 17, 2010

Signing PowerShell Scripts – A Gotcha with ISE!

In some enterprise environments, signing PowerShell scripts and setting an execution policy to only run signed scripts is a useful control mechanism. It can avoid less skilled admins ‘fixing’ a script almost correctly and can avoid untested scripts from running. Of course, the malign admin can still cut/paste the scripts into the command line and do damage – but that same admin can nuke the registry, reformat a volume, etc. Script signing is just another layer of defence.

The Scripting Guys Team (well actually superstar MVP Ragnar Harper) has written a two part blog post on the subject of how to do script signing. Part 1 is a useful tutorial on how to setup your own PKI using Windows Server’s built in Certificate Service feature (AD CS as MSFT call it). With Part 1, you learn how to get your code signing digital certificate.  Part 2 then talks you through how to use that certificate to generate a signed script.

The demo is good and the instructions work well, however there is one small gotcha. If you use PowerShell ISE to edit and save your scripts, the technique shown in Part 2 will fail. Here’s what you will see (from the ISE).

image

As you can see, this results in a rather less than helpful “UnknownError”. Turns out the reason is simple: By default, ISE saves scripts in Unicode BigEndian format – which Set-Authenticode does not cater for. And worse, the ISE Save-As dialog does not give you any option to save in a more friendly encoding (ie ASCII!).

There are three solutions to this:

1. Use Notepad to re-save the file as ASCII, then sign it. This is suboptimal but it works.

2.  You can get ISE to save as Unicode (not BigEndian) using a small script, unfortunately not from the menus. Just run the following bit of code:

$psise.CurrentFile.Save([system.Text.Encoding]::Unicode)

3: You can get ISE to save as always as ANSI. As t add the following bit of code to your PowerShell ISE:

register-objectevent $psise.CurrentPowerShellTab.Files collectionchanged -action {
    # iterate ISEFile objects
    $event.sender | % {
        # set private field which holds default encoding to ASCII
        $_.gettype().getfield("encoding","nonpublic,instance").setvalue($_, [text.encoding]::ascii)
     }
}

Once this fragment is executed, probably by adding it to your Profile, scripts get saved as ANSI and can be signed just fine.

Note in the above, you can both save the current file as ASCII or auto-save as Unicode. Set-AuthenticodeSignature works with both encodings, just not the ISE normal default of Unicode BigEndian (just change ::ASCII to ::UNICODE or vice versa!). Personally, I now save as ASCII. But if you have non-ANSI characters in your scripts, set the default as Unicode!

And a tip of the hat to Oisin Grehan who posted about this on the MVP list and who has posted some of the above code on his blog here.

 

Sunday, January 18, 2009

Managing a Music archive with PowerShell

I have a lot of digital music, as many of my friends, and readers of this blog, know. I’ve been slowly getting around to writing some PowerShell scripts to manage this archive. This afternoon, someone asked me how many Jerry Garcia shows I had on my system. I could not recall off the top of my head, so I wrote a short script to do the counting, and published this over on my PowerShell Scripts blog. The Get-CountOfJerryShows.ps1 scritp may not, perhaps, be the most elegant of PowerShell scripts. And I know I could do it in fewer lines. But it works and it’s something I am likely to be able to read and understand in the future, if/when I want to update it.

The answer, thanks to PowerShell: I currently have 734 live Jerry Shows! This is in addition to my 1144 Grateful Dead shows.

The latter is a lot simpler, as I just store all the Grateful Dead Shows in a single folder. To get a count of Dead shows, I just type:

   1: cd m:\gd;(ls | where {$_.Name -match "^gd"}).count
Technorati Tags: ,

Friday, January 02, 2009

Posting PowerShell Scripts – one solution

On my PowerShell Scripts blog, I publish daily, or near daily, PowerShell scripts. I am slowly decorating the MSDN on-line library with PowerShell samples. I am also playing with the latest version of PowerShell V2 (aka CTP3) and the new auto-help feature.

Now that CTP3 is out, I’ve decided to change the way I posts scripts – I’ll use the auto-help approach, and include examples in the posted script. You may have noticed based on recently posted scripts. Well – those of you who look at my script blog have noticed. May have noticed. Or not…

In the past, when I’ve created a script, I use Live Writer to create the blog post. In that post, I copy in the script AND the results (each formatted separately). With V2 CTP3’s auto-help, I’ve decided to decorate each script post with documentation that includes expected output. All of this is neatly embedded into the script as posted, with expected output specified in the .EXAMPLE section in the opening comment block.

With the new auto-help format, I can also document the posted scripts better – a comment made on the blog some whiles back.

I’d be interested in thoughts on this idea. Suggestions naturally welcome.

Friday, December 26, 2008

Enums, Enum values and PowerShell

 

I’ve been reading Jeffrey Snover's discussions on ENUMs over on the PowerShell Team blog (here, and here). I knew most of this stuff and have  been playing with Enums and PowerShell for a while. I’ve created a bunch of sample scripts I’ve uploaded both to the MDSN Wiki and to my PowerShell Scripts blog. This morning, I stumbled upon an interesting use of Enums – parsing strings into Integer values, as shown on the MSDN Library at http://msdn.microsoft.com/en-us/library/system.globalization.numberstyles.aspx.

Effectively want I wanted to do was to convert the following C# code to PowerShell:

  1. // Parse the string, allowing a leading sign, and ignoring leading and trailing white spaces. 
  2. num = "    -45   "
  3. val = int.Parse(num, NumberStyles.AllowLeadingSign |  
  4.      NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite); 
  5. Console.WriteLine("'{0}' parsed to an int is '{1}'.", num, val); 

Initially, I could not work out how to use the enums  (In System.Globalization.NumberStyles). Thanks to Shay Levy, it turns out to be remarkably easy (although not quite as succinct as in C'#). Basically, in true PowerShell style, every enum value is just an object. Objects have properties, and one property of an enum value is “value__” as demonstrated here:

PSH [D:\foo]: [System.Globalization.NumberStyles]::AllowLeadingSign
AllowLeadingSign
PSH [D:\foo]: [System.Globalization.NumberStyles]::AllowLeadingSign | gm

   TypeName: System.Globalization.NumberStyles

Name        MemberType   Definition
----        ----------   ----------
CompareTo   Method       System.Int32 CompareTo(Object target)
Equals      Method       System.Boolean Equals(Object obj)
GetHashCode Method       System.Int32 GetHashCode()
GetType     Method       System.Type GetType()
GetTypeCode Method       System.TypeCode GetTypeCode()
ToString    Method       System.String ToString(), System.String ToString(String format, IFormatPr...
value__     Property     System.Int32 value__ {get;set;}
MSDN        ScriptMethod System.Object MSDN();

PSH [D:\foo]: [System.Globalization.NumberStyles]::AllowLeadingSign.value__
4
PSH [D:\foo]:

As you can see from this output, the enum [System.Globalization.NumberStyles]::AllowLeadingSign displays normally the value “AllowLeadingSign” , but if you use the .value__ property on this enum value, you get back a number – in this case a decimal 4 (0x0004). You can then combine these as follows to convert the above C# Code into PowerShell:

  1. $num = " -45 "
  2.   $val = [system.int32]::Parse($num, 
  3.                [System.Globalization.NumberStyles]::AllowLeadingSign.value__ + 
  4.                [System.Globalization.NumberStyles]::AllowLeadingWhite.value__ + 
  5.                [System.Globalization.NumberStyles]::AllowTrailingWhite.value__) 
  6. "'{0}' parsed to an int is '{1}'." -f $num, $val 

Thanks to Shay Levy for his post in the PowerShell newsgroup for helping me to work this out. FWIW: you can the results of this up on the MSDN Library and on my PowerShell Scripts blog.

 

Thursday, December 25, 2008

Merry Christmas

Today is Christmas day and I’m away from the computer, enjoying Christmas dinner with my wife and daughter – I’m off the grid! As is our tradition, we’ll start with a nice bottle of Champagne and some smoked salmon. Then a bottle of Opus 1, with some cold roast duck, along with roasted turkey and roasted boneless chicken. We’ll finish up with some pudding and a nice bottle of vintage port. If anyone’s in the area and is not driving, they would be most welcome – I’d be happy to open up another bottle or two should that prove needed!

There’s no real PowerShell content today, but in keeping with the spirit of the season, there’s a fun PowerShell script up on PowerShell.Com to keep you amused. Enjoy.

And for the real hard-core PowerShell Addict, I’ll be posting tomorrow with some interesting stuff I discovered about using Enums and .NET. Stay tuned.

Merry Christmas and Seasons Greetings to you all.

Thursday, November 27, 2008

Some Cool PowerShell Scripts For Free

One of the more interesting PowerShell books currently in print is Lee Holmes’s most excellent book, PowerShell Cookbook. This book contains loads of samples and examples of how to use PowerShell. Although the first chapter of the book contains some introductory PowerShell background, this is very much an applied book. It shows how to use the basic PowerShell Language (e.g. Chapter 4 looks at loops and flow control, Chapter 5 examines strings and unstructured text, etc). It also contains information on extending the reach of PowerShell as well as a chapter on Security and Scripts signing. All in all, a very useful book on PowerShell V1 – and I hope it’s updated for Version 2.

One neat thing - the example scripts in  are available for free. Just navigate to http://examples.oreilly.com/9780596528492/ and click on the link to PowerShellCookbook S… to download a 54kb zip file that contains 65 documented scripts (and a few additional files used by some of the scripts).

Technorati Tags: ,,