Saturday, July 15, 2017

Managing Azure with PowerShell - A Spiceworks Blog Series

One of my fun tasks these days is being a group administrator and moderator on Spiceworks community forums. The forums are IT Pro focused and include a great group dedicated to all things PowerShell. If you have issues or questions, you are most welcome to come on over and post away. If you know PowerShell, we'd love to have more folks answering the torrent of questions we get.

In that role, Spiceworks asked me to create a series of blog posts on the Spiceworks Cloud blog which covers PowerShell and how you use it in the context of Azure. I offered to update some of the content in my upcoming book (See http://tfl09.blogspot.co.uk/2017/04/my-next-powershell-book.html for details). The publisher (Packt Publishing) kindly agreed.

The first article, Introduction to Managing Azure Services Using Windows PowerShell, was posted this week. The next blog post, which looks at getting the modules you need to manage  Azure whould be posted sometime next week. A third article on the basics of Azure storage and how to create an SMB share (and access the share across the Internet) is planned and should follow on in due course.

I have a number of additional posts to create, including one on building a Virtual Machine, and another on virtual networks and creating a P2S VPN into the VM. I am very much open to suggestions for more in this series.


Thursday, July 13, 2017

Hyper-V and PowerShell - A Tale of Two Modules

I've been working on a book project (see: http://tfl09.blogspot.co.uk/2017/04/my-next-powershell-book.html for details!) and have been working a lot with Hyper-V. I've built a nice farm of VMs (18 or so) representing a bunch of server roles and features. Then, I've been using PowerShell to exercise those roles and features.

These VMs all run on client Hyper-V, on a Windows 10 (AU) host that has 96gb or ram, 2x6-core XEON processors, and loads of disk. The VMs are nearly all running Windows 2016 Server. The chapters all utilise AD/DNS/DHCP/CA etc. A nice setup for writing a book.

In writing, I've noticed that Windows 10 as well as Windows Server 2016 both ship with two Hyper-V modules. The two modules are version 1.1 and 2.0.0.0, as you can see here:


The version 2.0.0.0 module is a superset of the version 1.1 module. Version 1.1 contains 178 cmdlets, while  version 2.0.0.0 contains 235. Both modules have display XML included. Both versions use the same file name, but the Version 2.0.0.0 copy is larger.

You could, or course, manually load version 1.1 module like this:
Import-Module -Name Hyper-V -MaximumVersion 1.1
So long as you just use the cmdlets in the 1.1 version, you would be safe, but if your script did load 1.1, then trying to use cmdlets in the 2.0.0.0 module generates what at first sight is a curious message:


The error message is also both wrong and, if taken, confusing. Importing the module as suggested by the error message generates more error messages. The error messages (Error in TypeData, etc) occur because Powershell is trying to load the version 2.0.0.0 copy of the display XML, and most of the components were already loaded from the 1.1 version. And even if you ignore the display XML errors, the suggested solution still fails with the same error message.

The solution to this error is easy: update your scripts to not explicitly load v1.1. OR, if you do need for some reason to use the 1.1 version and use cmdlets in 2.0.0.0, then pressed them with a 'Get-Module Hyper-V | Remove-Module Hyper-V' and then follow the 2.0.0.0 cmdlet with commands to remove the module and reload the 1.1 version. Personally, while that could work, it's awfully messy and possibly not needed.

Does having two versions really matter?  If you just use cmdlet names in the Hyper-V module, such as Get-VM, then PowerShell by default loads version 2.0.0.0.  If your script uses Import-Module to load the Hyper-V module explicitly, then again by default, PowerShell loads 2.0.0.0.  Having written over 100 scripts across a dozen different Server 2016 features and roles - I never noticed any problems. My scripts, with a few exceptions, relied on PowerShell's module autoload feature - I called the cmdlet and PowerShell loaded one.

If your scripts, on the other hand, explicitly load V 1.1 (as shown above), then you may get a strange error. But in most cases, that can be avoided by simply not explicitly loading version 1.1 of the module. Now I know there may be cases where you may need to use a V 1.1 cmdlet, but those cases should be pretty rare.


Monday, June 26, 2017

Setting Application Pool Recycling Values with PowerShell

As I mentioned a while ago, I'm working on a new PowerShell book (See http://tfl09.blogspot.co.uk/2017/04/my-next-powershell-book.html for details! In writing the book, I've been creating simple scripts to do useful things. In researching them, I found a number of aspects really well covered, reference wise. Other things were not covered well if at all. I hope to post some things I've discovered in the coming months.

With IIS, you can create applications that run in application pools. An application is some set of web pages (with related executables). An application pool is a process, or processes, that run this application. This provides process isolation between applications reducing the impact a badly behaved application can have on other applications running on the same server. Resource leaks can bring an entire web server down, for example.

One way to minimise these sorts of issues is to recycle the application pool - just stop then restart the processes running the application. A neat trick that reduces the risks of resource leaks. One downside is that any state within the application is lost. Needless to say, there are other ways to save state that are not affected by an application pool restart. For a fuller look at the things you can do to configure application pools, see: https://technet.microsoft.com/en-us/library/cc745955.aspx. This document is old, but is a good starting point (and worked fine on IIS 10 for my needs).

You set application pool recycling values, using PowerShell, by setting item properties on certain items within the WebAdministration provider (the IIS: drive). This is simple, but the property names are not all that obvious at first.

What I wanted to do was:

  • Set specific times at which to recycle the application pool
  • Set the pool to automatically if private memory rises beyond a limit, say 1GB.
  • Set the pool to recycle the pool after the pool processes a certain number of requests, say 1 million.

In PowerShell, once you know where to look, this is simple:

# Set Application Pool Restart time
Clear-ItemProperty IIS:\AppPools\WWW2Pool -Name Recycling.periodicRestart.schedule
$RestartAt = @('07:55', '19:55') 
New-ItemProperty -Path 'IIS:\AppPools\WWW2Pool' -Name Recycling.periodicRestart.schedule -Value $RestartAt

# Set Application Pool Maximum Private memory
Clear-ItemProperty IIS:\AppPools\WWW2Pool -Name Recycling.periodicRestart.privatememory
[int32] $PrivMemMax = 1GB
Set-ItemProperty -Path "IIS:\AppPools\WWW2Pool" -Name Recycling.periodicRestart.privateMemory -Value $PrivMemMax

# Set max requests before a recycle
Clear-ItemProperty IIS:\AppPools\WWW2Pool -Name Recycling.periodicRestart.requests
[int32] $MaxRequests = 100000
Set-ItemProperty -Path "IIS:\AppPools\www2POOL" -Name Recycling.periodicRestart.requests -Value $MaxRequests

Some things that caught me out a bit:
1. Finding out the property names. In the case of recycling after 1m hits, the property name is 'Recycling.periodicRestart.PrivateMemory'. I suspect this naming is used by the provider to access the underlying XML that IIS actually uses to hold configuration information.
2. Finding values is easy, if there is one. I found the easitest way to set these values was to first clear the property, then set it.
3. Some item properties take properties of a certain type. It helps to specify the type (as shown above) as some times PowerShell tries to be helpful which can confuse the provider.


Tuesday, May 02, 2017

AD User Properties In PowerShell

I spend a lot of time as a Group Administrator looking after the PowerShell forum over on Spiceworks. The PowerShell group has an active forum  which you can find over at https://community.spiceworks.com/programming/powershell,

One issue that arises often is around getting properties back from a user object in Windows Active Directory. Typically we see posters knowing the GUI interface in Active Directory Users and Computers (ADUC), and wanting to get the same details. Although it is NOT new, I found a great resource the other day: Mappings for the Active Directory Users and Computers Snap-in.

This page, which has numerous subpages, maps the fields you find on the property sheets inside the ADUC MMC snap-in to the properties names you get/set using the Microsoft provided AD cmdlets.

For example, if you have set an Office address on the OU Managed By property sheet, you need to use the Physical-Delivery-Office-Name property from Get-Organizational unit to obtain that information. Likewise, the General Property Page for a user object shows First Name (property givenName), Last Name (sn), and the Display Name (displayName).

This page has links for:

  • Computer Object User Interface Mapping
  • Domain Object User Interface Mapping
  • Group Object User Interface Mapping
  • Object Property Sheet
  • Organizational Unit User Interface Mapping
  • Printer Object User Interface Mapping
  • Shared Folder Object User Interface Mapping
  • User Object User Interface Mapping
If you are working with the AD cmdlets and you need to map what you see in the ADUC GUI to what you need to use in PowerShell.

Saturday, April 29, 2017

Top 50 PowerShell Blogs

I just got e-mail that this blog has been included in the Feedspot.Com's Top 50 PowerShell Blogs list. You can see this list over at http://blog.feedspot.com/powershell_blogs/

I started this blog in 2003 - and first blogged about PowerShell (well, it was called Monad in those days) on 1 Nov 2003. It's been a long run with PowerShell - since that first day when Jeffrey Snover presented 'Batch Scripting, what you can do in 7 lines of code' to PDC 2003.

As Robert Hunter once wrote (and the Grateful Dead sang) "What a long strange trip it's been".

My Next PowerShell Book

Along with a colleague, David Cobb, I'm working on a new PowerShell book. The book's title is Windows Server 2016 Automation with PowerShell Cookbook (ISBN: 978-1-78712-204-8).  The focus of the book is showing how to manage key Windows Server 2016 features using the latest versions of PowerShell. For each area covered, we show how to do things using Powershell, in the form of recipes. Our intention is to both teach a bit about the feature itself, and show you how to manage the feature using built-in and add-on modules.

In a few cases, there is no built-in way to perform some operation using PowerShell. My favourite example is that the Printing cmdlets provide no way to create a printer pool, but you can in then UI. In that case, and others, the book shows useful Win32 console applications. In the case of printer pools, we show how to use PrintUI.DLL and RunDll32.EXE to set up a printer pool. IT pros can't yet do everything with PowerShell, out of the box - but in many cases, that's just not a problem.

The book has 16 chapters, as follows:
  • What’s New in PowerShell
  • Implementing NanoServer
  • Managing Windows Updates
  • Managing Printers
  • Manage Storage
  • Managing Server Backup
  • Managing Performance
  • Troubleshooting Servers
  • Inventorying Servers
  • Managing Windows Network Services
  • Managing Network Shares
  • Managing IIS
  • Managing Hyper-V
  • Managing Containers
  • Managing Azure
  • Using Desired State Configuration
At the time of this post, we're nearly done the drafting of the book's contents, and entering into the slow, tedious, and boring part: the editing and final proofing. It may be slow, tedious, and boring, but it's very important, as any writer knows.

We had a bit of a hiccough with the writing, but it's looking now like this book will be published over the summer. As soon as I have a more definitive date, I'll post it./

Saturday, January 28, 2017

Nested Hyper-V with Windows 10

I've been away all week, teaching in Trondheim Norway. A nice place, great students and a useful Microsoft training course. In the course, Hyper-V features quite a lot - one cool feature discussed in nested Hyper-V.

Nested Hyper-V is a feature that enables you to create a virtual machine, and then load Hyper-V into that machine. So you can have a VM running VMs. This feature is cool, certainly at a technical level. No doubt someone is going to point out that VMware supports this, but the feature is new in Hyper-V on Server 2016. And interestingly enough, it works in Windows 10 Anniversary Update too!

Why does it matter?  For me, it matters since I am writing a book on PowerShell showing its range and depth. One chapter covers Hyper-V and having Nested Hyper-V means I can create two VMs (HV1, HV2) cluster the VMs, then create clustered virtual machines, The chapter is now easier to write.

The feature matters for customers too.  This enables you to use Hyper-V containers within a VM on a VM. And, it's a fantastic training tool when using on-line labs. The lab vendor, such as Virsoft (a great hosted labs experience!), to provide a student with a VM, in which they can load and use Hyper-V. Previously that was unsupported.

Getting nested Hyper-V to work is great news. For some time, I believed that this would not work on my systems. I have three big Dell Precision 7500 systems. When I tried this during the beta of Windows Server 2016, Coreinfo.exe suggested that my system did not support SLAT. And that meant I could not use nested Hyper-V. But it was wrong!

Here's a picture of a VM hosting a nested VM:
As you can see, a VM running a nested VM. The nested VM, which I called 'embedded' is in the midst on installation.

It turns out that the fix was pretty simple. In the host VM, I just had to issue a simple PowerShell command:

Set-VMProcessor -VMname DC1-ExposeVirtualizationExtensions $True
I had to shut down the  VM first, then reboot. Once rebooted, I was able to bring up the Hyper-V console and create the embedded VM.




Saturday, January 21, 2017

Grammarly

Last year, I wrote about a few great writing aids. One of the tools was Grammarly.

Grammarly is a browser plug in for the Chrome browser which provides spelling and grammar advice. A spell and grammar checker on steroids. On my main writing workstation, I have Grammarly loaded and running all the time. It almost feels like a part of the underlying browser, but with nice bells and whistles.

I am currently working on a book for Packt, and we have a sweet content development portal. We just go to the web site and use the text editing features to enter the text and graphics. We can then output to PDF - it works well. Inside this CDP, Grammarly is wonderful!

When I am entering content in the CDP, you can see Grammarly when it has something it's not happy with, like this:



If you hover over the red squiggly, Grammarly displays a little pop up box that gives you options - in this case some spelling alternatives. From that little popup, you can click on 'Correct with Grammarly', and a larger box appears with more advice. From this second pop up, you can scroll through your entire document to see where Grammarly feels you should make a change. It's awesome.

In practice, I write and insert code/pics, then repeat and repeat. I touch type, but not with perfect accuracy. For me, at least, it's faster to leave a typo in the sentence and continue typing than to fix the error then carry on. I can then just use the mouse to fix the errors - and that works well for me!

The free version is excellent. But for a fee, there's a Professional version that adds a significant number of additional grammar checking rules, including passive voice as well as a plagiarism checker. The Pro version is billed either monthly ($US 37.95), quarterly ($US 24.98), and annually ($US 11.66). At the moment, there is a 20% reduction - but I do now know how long that will last - with the discounts the prices are $29.95, $19.98, and 11.66 per month).

On the downside, several of us have noticed that with Grammarly turned on, our content deployment system can crash. This is a pain, but regular saves, autosave turned on, and bit of experience - recovery is usually pretty easy. I can live with the occasional hang in exchange for such a great product.


Friday, January 20, 2017

WMF 5.1 released for download

When Microsoft ships a new version of PowerShell, it issues what they call the Windows Mangement Framework (WMF). The WMF package includes a new version of PowerShell, updated core cmdlets, and includes updated versions of other related components (e.g. an updated WMI).

In a blog post on the MS Site, Microsoft announced that release of the WMF 5.1 package. The blog post makes it clear that WMF 5.1 upgrades Window 8, Windows 8.1, Windows Server 2008 R2, Windows Server 2012, and Windows Server 2012 R2 to the PowerShell, WMI, WinRM, and SIL components that were released with Windows Server 2016 and Windows 10 Anniversary Edition.

If you are using Windows 7 or Windows Server 2008 R2, you should be a little careful installing this package. The installation instructions were changed - so read the release notes carefully. 

It should be clear from the blog post, but if not: if you are using Windows 10 AU or Windows Server 2016, there is nothing for you to do. Those two operating systems ship with WMF 5.1 installed.

Wednesday, January 18, 2017

Using Get-CimAssociatedInstance

Tonight I finally found a use for the Get-CimAssociatedInstance cmdlet. I know what that cmdlet does, but never had a real use case, until tonight. 

What I was trying to do was to use the CIM cmdlets to find the logged-on user. 

Initially, I searched through the many Win32_Classes and found one that looked promising (Win32_LogonSession). So I tried looking at the interactive logons:
Get-CimInstance Win32_LogonSession |         Where-Object LogonType -EQ 10
But that returned me a somewhat unhelpful response:


I wanted the username (and the SID). So I searched around a bit and found a class name that looked appealing: win32_loggedonuse. Turns out this is one an associator class. In WMI, the associator associates two other instances in the WMI database. In this case. the associator class associates a Win32_LogonSession with the WIn32_Account that is logged on in that session.

So I turned it into a tool :.
Function Get-WhoIAm {
# Get Account for the loggede on user$Me = Get-CimINstance Win32_LogonSession |         Where-Object LogonType -EQ 10 |           Get-CimAssociatedInstance -Association win32_loggedonuser
# Extract useful properties$IAmHT = [ordered] @{}$IAmHT.Account            = $Me.Caption$IAmHT.Description        = $Me.Description$IAmHT.LocalAccount       = $Me.LocalAccount$IAmHT.PasswordChangeable = $me.PasswordChangeable$IAmHT.SID                = $Me.SID$IamHT.CommputerName      = (Get-CimInstance -Classname Win32_Computersystem).Name
# Create a new object$IAm = New-Object -TypeName PSCustomObject -Property $IAmHT
# And return the Iam objectreturn $IAm
}
And for fun, I set an alias of WhoAmi - a tool I've used for a decade or longer. With that done, the output looks like this:


Happy days with WMI and the CIM Cmdlets.