Shared posts

01 Jan 17:40

10 Amazing Facts About Google You Probably Didn’t Know

by Jackson Chung
amazing-google-facts-feat

Fact #1: Believe it or not, the Google homepage is so bare mainly because Sergey Brin and Larry Page didn’t know HTML and just wanted a quick interface. Since then, Google has grown to be used by at least everyone on the planet, and processes around 20 petabytes of information on a daily basis. In the past 5 years, it has indexed over 50 billion web pages, and hosts over 620 million visitors a day. Do you have more amazing facts about Google? Share them in the comments. Click to enlarge. via promodo.com

Read the full article: 10 Amazing Facts About Google You Probably Didn’t Know

28 Dec 10:03

Windows To Go, Ironkey and ConfigMgr 2012 R2 better together – part 2

by Peter Daalmans

After we have looked at the initialization process of the Ironkey device, we will dive Read more

The post Windows To Go, Ironkey and ConfigMgr 2012 R2 better together – part 2 appeared first on Configuration Manager Blog.

27 Dec 14:23

Setup a Windows Server 2012 R2 Domain Controller in Windows Azure: IP Addressing and Creating a Virtual Network

by Russell Smith

While it’s easy to get a virtual machine (VM) up and running on Windows Azure, you need to take some extra steps before configuring a VM if it’s going to host an Active Directory domain controller or any application that requires a static IP address. In the first of a two-part series on how to install a domain controller in a Windows Azure virtual machine, I’ll look at how IP addressing works in Windows Azure and how to create a virtual network for your domain computers.

IP Address Assignment in Windows Azure

When you configure a new VM in Windows Azure, it receives an IP address automatically and keeps it until the end of the current session, i.e. until the VM is shutdown, restarted or deallocated. Configuring a network adapter with a static IP address is not supported in Azure VMs, but it is possible to ensure that a VM receives the same IP address every time it is started.

Server applications, such as Active Directory domain controllers (DCs), rely on having a static IP address, so the default method for assigning IP addresses in Azure is a problem if you want to install Active Directory in a VM. The solution to the problem is to create a virtual network in Azure and provision VMs that would require a static IP address in a physical environment to acquire a persistent IP address in Azure.

When you create a virtual network, you need to specify which IP address will be used for AD integrated DNS. In the example that follows, that will be the first and only DC in the forest. The IP address for the integrated AD DNS server must be specified to ensure that VMs are assigned a DNS server address from DHCP, otherwise they won’t be able to locate each other because Azure virtual networks don’t support name resolution.

No DHCP reservations are required or can be made. When Windows Azure assigns a persistent IP address to a VM from a virtual network’s address space, the IP address is guaranteed for the lifetime of the VM. The VM can be restarted infinitely, and the IP address will persist until the VM is physically deleted or deallocated (shut down from the Azure management portal). Therefore, it’s important to understand that if you use the shutdown command in the Azure management portal, the VM will be deallocated and its IP address will not persist. If you want to shut down the VM, you must issue a shutdown command in the OS itself.

Build Windows Server 2012 R2 DC in Azure: VM status

If you shut down the OS using the operating system, and the VM was provisioned with a persistent IP address, it will eventually show a Stopped status in the Azure management portal. VMs without a persistent IP will change their status to Stopped (Deallocated). Don’t forget Azure VMs that are not deallocated use compute resources and can incur charges.

Register a DNS Server (in DHCP)

Prior to creating a virtual network, we need to specify which IP address will serve as a DNS server. In this case, it will be our first domain controller. I’m choosing to use a private address range of 192.168.0.0/24, but you can use any valid IPv4 private address range.

Login to the Windows Azure management portal. If you don’t ready have an Azure account, you can sign up for a free evaluation.

  • In the left pane of the Windows Azure management portal, click Networks.
  • In the main pane of the management console under networks, click DNS Servers.
  • Click Register a DNS Server.
  • In the pop-up NEW dialog, give the new DNS server a name and IP address. In this example, I’ll call my DNS server CONTOSODNS1 and with 192.168.0.4 as the IP address. Once you are done, click Register a DNS Server in the bottom right-hand corner.

Build Windows Server 2012 R2 DC in Azure: register DNS server

In Azure, the first three IP addresses are not available in private address ranges, so I know that the first usable IP address will be 192.168.0.4.

The new DNS server should now appear in the management portal. At the bottom you’ll see a message to say that the DNS server is being provisioned.

  • Click on the green provisioning icon in the bottom right of the management console to see the current status of the new DNS server. Provisioning should complete after a minute or so.
  • Click OK to dismiss the message.

Create a Virtual Network

Now we need to create a virtual network in the management portal. I’m going to create a virtual network using the 192.168.0.0/24 address space, but you could equally choose to use the default 10.0.0.0/8 address space.

  • In the Azure management portal, make sure that Networks is still selected in the left pane, and then click Virtual Networks under networks in the main window.
  • Click Create a Virtual Network.
  • In the pop-up dialog, give the new network a name and select an affinity group.

Build Windows Server 2012 R2 DC in Azure: name Virtual network

In this example, I will call the new network CONTOSONET1 and select the preexisting Contoso affinity group. If you don’t already have an affinity group in Azure, you can select Create a new affinity group from the drop-down menu. If you create a new affinity group at this stage, you will additionally need to select a region and give the new affinity group a name.

  • To continue, click the arrow in the bottom right of the Create a Virtual Network window.
  • Under DNS Servers and VPN Connectivity, select CONTOSODNS1 as the DNS server.

 

Build Windows Server 2012 R2 DC in Azure: Add a DNS server

The Point-to-Site Connectivity and Site-to-Site Connectivity options do not need to be configured.

  • Click the arrow in the bottom right to continue.
  • On the Virtual Network Address Spaces screen, click add address space.172.16.0.0/12 will be added to the existing 10.0.0.0/8 address space. Click the 172.16.0.0 starting IP address and select 192.168.0.0 from the drop-down menu. Under CIDR (Address Count), leave the default select of /24 (256).
  • Now delete the default 10.0.0.0/8 address space by clicking the cross to the far right of the 10.0.0.0/8 address space configuration.
  • Under Subnets, change the name of the subnet to Subnet-1 and the CIDR (Address Count) to /24 (256).
  • When you’re done, click the tick symbol in the bottom right corner of the window.

Build Windows Server 2012 R2 DC in Azure: Configure IP address space

You should now see the new network appear in the main portal window, and see the status change to Created after around 30 seconds.

In the second part of this series, I’ll show you how to provision a new VM with a persistent IP address, and how to correctly install the AD DS role and promote the server to a domain controller.

27 Dec 14:15

Veeam releases free RDP Appliance for Hyper-V Server

Microsoft has a free hypervisor offering called Hyper-V Server 2012 R2. Hyper-V Server 2012 R2 is fully equal to the Hyper-V role in Windows Server 2012. The only item not available in the free edition is the free usage rights for virtual machines running on a host installed with Hyper-V. Each virtual machine instance running on free Hyper-V Server 2012 R2 needs to be licensed....
21 Dec 15:40

System Center Operations Manager and Azure: Better Together with the Azure Monitoring Gateway Part 1 and 2

One of the great things I love about my job is the amount of really smart and talented folks I get to work with. This is so true with my good friend Cameron Fuller. Some of you may know Cameron and read is blog, he truly is a System Center expert. Often times, when I folks like Cameron are on the cutting edge of our technologies. For this post I caught wind of a great series...
21 Dec 15:29

Managing Office365 with PowerShell

by ps1

Did you know that you can manage your Office365 accounts with PowerShell, too? Provided you have an Office365 account, try this:

$OfficeSession = New-PSSession -ConfigurationName Microsoft.Exchange `
-ConnectionUri https://ps.outlook.com/powershell/ -Credential (Get-Credential) `
-Authentication Basic -AllowRedirection $import = Import-PSSession $OfficeSession -Prefix Off365 Get-Command -Noun Off365*

This will connect to Office 365 with your credentials, and then import the PowerShell cmdlets you can use to manage it. You'll get roughly 400 new cmdlets. If you get an "Access Denied" instead, then your account may not have sufficient privileges, or you mistyped your password.

Note that all imported cmdlets are prefixed with "Off365", so to view all mailboxes, try this:

 

You can choose the prefix yourself (see code above) which enables you to connect to multiple Office365 accounts at the same time and using different prefixes. You can omit the prefix, too, when you run Import-PSSession.

To view the new commands that were exported by Office365, use this:

$import.ExportedCommands 

Twitter This Tip! ReTweet this Tip!

21 Dec 10:52

Enabling Linux Support on Windows Server 2012 R2 Hyper-V

by Ben Armstrong [MSFT]

This post is a part of the nine-part “What’s New in Windows Server & System Center 2012 R2” series that is featured on Brad Anderson’s In the Cloud blog.  Today’s blog post covers Linux Support on Windows Server 2012 R2 and how it applies to Brad’s larger topic of “Transform the Datacenter”.  To read that post and see the other technologies discussed, read today’s post:  “What’s New in 2012 R2:  Enabling Open Source Software.” 

The ability to provision Linux on Hyper-V and Windows Azure is one of Microsoft’s core efforts towards enabling great Open Source Software support. As part of this initiative, the Microsoft Linux Integration Services (LIS) team pursues ongoing development of enlightened Linux drivers that are directly checked in to the Linux upstream kernel thereby allowing direct integration into upcoming releases of major distributions such as CentOS, Debian, Red Hat, SUSE and Ubuntu.

The Integration Services were originally shipped as a download from Microsoft’s sites. Linux users could download and install these drivers and contact Microsoft for any requisite support. As the drivers have matured, they are now delivered directly through the Linux distributions. Not only does this approach avoid the extra step of downloading drivers from Microsoft’s site but it also allows users to leverage their existing support contracts with Linux vendors.

For example Red Hat has certified enlightened drivers for Hyper-V on Red Hat Enterprise Linux (RHEL) 5.9 and certification of RHEL 6.4 should be complete by summer 2013. This will allow customers to directly obtain Red Hat support for any issues encountered while running RHEL 5.9/6.4 on Hyper-V.

To further the goal of providing great functionality and performance for Linux running on Microsoft infrastructure, the following new features are now available on Windows Server 2012 R2 based virtualization platforms:

 

  1. Linux Synthetic Frame Buffer driver – Provides enhanced graphics performance and superior resolution for Linux desktop users.
  2. Linux Dynamic memory support – Provides higher virtual machine density/host for Linux hosters.
  3. Live Virtual Machine Backup support – Provisions uninterrupted backup support for live Linux virtual machines.
  4. Dynamic expansion of fixed size Linux VHDs – Allows expansion of live mounted fixed sized Linux VHDs.
  5. Kdump/kexec support for Linux virtual machines – Allow creating kernel dumps of Linux virtual machines.
  6. NMI (Non-Maskable Interrupt) support for Linux virtual machines – Allows delivery of manually triggered interrupts to Linux virtual machines running on Hyper-V.
  7. Specification of Memory Mapped I/O (MMIO) gap – Provides fine grained control over available RAM for virtual appliance manufacturers.

All of features have been integrated in to SUSE Linux Enterprise Server 11 SP3 which can be downloaded from SUSE website (https://www.suse.com/products/server/). In addition integration work is in progress for the upcoming Ubuntu 13.10 and RHEL 6.5 releases.

 Further details on these new features and their benefits are provided in the following sections:

 1.       Synthetic Frame Buffer Driver

 The new synthetic 2D frame buffer driver provides solid improvements in graphics performance for Linux virtual machines running on Hyper-V. Furthermore, the driver provides full HD mode resolution (1920x1080) capabilities for Linux guests hosted in desktop mode on Hyper-V.

 One other noticeable impact of the Synthetic Frame Buffer Driver is elimination of the double cursor problem.  While using desktop mode on older Linux distributions several customers reported two visible mouse pointers that appeared to chase each other on screen. This distracting issue is now resolved through the synthetic 2D frame buffer driver thereby improving visual experience on Linux desktop users.

 2.       Dynamic Memory Support

 The availability of dynamic memory for Linux guests provides higher virtual machine density per host. This will bring huge value to Linux administrators looking to consolidate their server workloads using Hyper-V. In house test results indicate a 30-40% increase in server capacity when running Linux machines configured with dynamic memory.

 The Linux dynamic memory driver monitors the memory usage within a Linux virtual machine and reports it back to Hyper-V on a periodic basis. Based on the usage reports Hyper-V dynamically orchestrates memory allocation and deallocation across various virtual machines being hosted. Note that the user interface for configuring dynamic memory is the same for both Linux and Windows virtual machines.

 

The dynamic Memory driver for Linux virtual machines provides both Hot-Add and Ballooning support and can be configured using the Start, Minimum RAM and Maximum RAM parameters as shown in Figure 1.

Upon system start the Linux virtual machine is booted up with the amount of memory specified in the Start parameter.

If the virtual machine requires more memory then Hyper-V uses the Hot-Add mechanism to dynamically increase the amount of memory available to the virtual machine.

On the other hand, if the virtual machine requires less memory than allocated then Hyper-V uses the ballooning mechanism to reduce the memory available to the virtual machine to a more appropriate amount.

 

Figure 1 Configuring a Linux virtual machine with Dynamic Memory

 Increase in virtual machine density is an obvious advantage of use of dynamic memory. Another great application is the use of dynamic memory in scaling application workloads. The following paragraphs illustrate an example of a web server that was able to leverage dynamic memory to scale operations in the event of increasing client workload.

 For illustrative purposes, two apache servers hosted inside separate Linux virtual machines were set up on a Hyper-V server. One of the Linux virtual machines was configured with a static RAM of 786 MB whereas the other Linux virtual machine was configured with dynamic memory. The dynamic memory parameters were setup as follows: Startup RAM was set to 786MB, Maximum RAM was set to 8GB and the Minimum RAM was set to 500MB. Next both apache server were subjected to monotonically increasing web server workload through a client application hosted in a Windows virtual machine.

 Under the static memory configuration, as the apache server becomes overloaded, the number of transactions/second that could be performed by the server continue to fall due to high memory demand. This can be observed in Figure 2 and Figure 3. Figure 2 represents the initial warm up period when there is ample free memory available to the Linux virtual machine hosting apache. During this period the number of transactions/second is as high as 103 with an average latency/transaction of 58ms.

 

 Figure 2 Server and Client statistics during initial warm up period for the Linux apache server configured with static RAM

 As the workload increases and the amount of free memory becomes scarce, the number of transactions/second drops to 32 and the average latency/transaction increases to 485ms. This situation can be observed in Figure 3.

 

 Figure 3 Server and client statistics for an overloaded Linux apache server configured with static RAM

 Next consider the case of the apache server hosted in a Linux virtual machine configured with dynamic memory. Figure 4 shows that for this server the amount of available memory quickly ramps up through Hyper-V’s hot-add mechanism to over 2GB and the number of transactions/second is 120 with an average latency/transaction of 182 ms during the warm up phase itself.

  

Figure 4 Server and client statistics during startup phase of Linux apache server configured with Dynamic RAM

 As the workload continues to increase, over 3GB of free memory becomes available and therefore the server is able to sustain the number of transactions/second at 130 even though average latency/transaction increases to 370ms. Notice that this memory gain can only be achieved if there is enough memory available on the Hyper-V server host. If the Hyper-V host memory is low then any demand for more memory by a guest virtual machine may not be satisfied and applications may receive no free memory errors.

 

Figure 5 Overloaded Linux apache server configured with Dynamic RAM

3.       Live Virtual Machine Backup Support

A much requested feature from customers running Linux on Hyper-V is the ability to create seamless backups of live Linux virtual machines. In the past customers had to either suspend or shutdown the Linux virtual machine for creating backups. Not only is this process hard to automate but it also leads to an increase in down time for critical workloads.

To address this shortcoming, a file-system snapshot driver is now available for Linux guests running on Hyper-V. Standard backup APIs available on Hyper-V can be used to trigger the driver to create file-system consistent snapshots of VHDs attached to a Linux virtual machine without disrupting any operations in execution within the virtual machine.

The best way to try out this feature is to take a backup of a running Linux virtual machine through Windows Backup. The backup can be triggered from the Windows Server Backup UI as shown in Figure 6. As can be observed the live virtual machine labeled OSTC-Workshop-WWW2 is going to be backed up. Once the backup operation completes a message screen similar to Figure 7 should be visible.

 

 Figure 6 Using Windows Server Backup to backup a live Linux virtual machine

 Figure 7 Completion of backup operation for a live Linux virtual machine

One important difference between the backups of Linux virtual machines and Windows virtual machines is that Linux backups are file-system consistent only whereas Windows backups are file-system and application consistent. This difference is due to lack of standardized Volume Shadow Copy Service (VSS) infrastructure in Linux.

4.       Dynamic Expansion of Live Fixed Sized VHDs

The ability to dynamically resize a fixed sized VHD allows administrators to allocate more storage to the VHD while keeping the performance benefits of the fixed size format. The feature is now available for Linux virtual machines running on Hyper-V. It is worth noting that Linux file-systems are quite adaptable to dynamic changes in size of the underlying disk drive. To illustrate this functionality let us look at how a fixed sized VHD attached to a Linux virtual machine can be resized while it is mounted.

First, as shown in Figure 8, a 1GB fixed sized VHD is attached to a Linux virtual machine through the SCSI controller. The amount of space available on the VHD can be observed through the df command as shown in Figure 9.

Figure 8 Fixed Sized VHD attached to a Linux virtual machine through the SCSI Controller

 

Figure 9 Space usage in the Fixed Sized VHD

Next, a workload is started to consume more space on the fixed sized VHD. While the workload is running, when the amount of used space goes beyond the 50% mark (Figure 10), the administrator may increase the size of the VHD to 2GB using the Hyper-V manager UI as shown in Figure 11.

 

Figure 10 Amount of used space goes beyond 50% of the current size of the Fixed Sized VHD

   

Figure 11 Expanding a Fixed Size VHD from 1GB to 2GB

Once the VHD is expanded, the df command will automatically update the amount of disk space to 2GB as shown in Figure 12. It is important to note that both the disk and the file-system adapted to the increase in size of the VHD while it was mounted and serving a running workload.

 

Figure 12 Dynamically adjusted df statistics upon increase in size of Fixed Sized VHD

5.       Linux kdump/kexec support

One particular pain point for hosters running Linux on Windows Server 2012 and Windows Server 2008 R2 environments is that legacy drivers (as mentioned in KB 2858695 ) must be used to create kernel dumps for Linux virtual machines.

In Windows Server 2012 R2, the Hyper-V infrastructure has been changed to allow seamless creation of crash dumps using enlightened storage and network drivers and therefore no special configurations are required anymore. Linux users are free to dump core over the network or the attached storage devices.

6.       NMI Support

If a Linux system becomes completely unresponsive while running on Hyper-V, users now have the option to panic the system by using Non-Maskable Interrupts (NMI). This is particularly useful for diagnosing systems that have deadlocked due to kernel or user mode components.

The following paragraphs illustrate how to test this functionality. As a first step observe if any NMIs are pending in your Linux virtual machines by executing the command in a Linux terminal session shown in Figure 13:

 

Figure 13 Existing NMIs issued to the Linux virtual machine

Next, issue an NMI from a powershell window using the command shown below:

Debug-VM -Name <Virtual Machine Name> -InjectNonMaskableInterrupt -ComputerName <Hyper-V host name> Confirm:$False –Force

Next check if the NMI has been delivered to the Linux VM by repeating the command shown in Figure 13. The output should be similar to what is shown in Figure 14 below:

 

Figure 14 New NMIs issued to the Linux virtual machine

7.       Specification of Memory Mapped I/O (MMIO) gap

Linux based appliance manufacturers use the MMIO gap (also known as PCI hole) to divide the available physical memory between the Just Enough Operating System (JeOS) that boots up the appliance and the actual software infrastructure that powers the appliance. Inability to configure the MMIO gap causes the JeOS to consume all of the available memory leaving nothing for the appliance’s custom software infrastructure. This shortcoming inhibits the development of Hyper-V based virtual appliances.

The Windows Server 2012 R2 Hyper-V infrastructure allows appliance manufacturers to configure the location of the MMIO gap. Availability of this feature facilitates the provisioning of Hyper-V powered virtual appliances in hosted environments. The following paragraphs provide technical details on this feature.

The memory of a virtual machine running on Hyper-V is fragmented to accommodate two MMIO gaps.  The lower gap is located directly below the 4GB address.  The upper gap is located directly below the 128GB address.  Appliance manufacturers can now set the lower gap size to a value between 128MB and 3.5GB. This indirectly allows specification of the start address of the MMIO gap. 

The location of the MMIO gap can be set using the following sample PowerShell script functions:

############################################################################
#
# GetVmSettingData()
#
# Getting all VM's system settings data from the host hyper-v server
#
############################################################################

function GetVmSettingData([String] $name, [String] $server)
{
    $settingData = $null

    if (-not $name)
    {
            return $null
    }

    $vssd = gwmi -n root\virtualization\v2 -class Msvm_VirtualSystemSettingData -ComputerName $server
     if (-not $vssd)
    {
        return $null
    }

    foreach ($vm in $vssd)
    {
        if ($vm.ElementName -ne $name)
        {
            continue
        }

        return $vm
    }

    return $null
}

###########################################################################
#
# SetMMIOGap()
#
# Description:Function to validate and set the MMIO Gap to the linux VM
#
###########################################################################
function SetMMIOGap([INT] $newGapSize)
{

    #
    # Getting the VM settings
    #
    $vssd = GetVmSettingData $vmName $hvServer
    if (-not $vssd)
    {
        return $false
    }

    #
    # Create a management object
    #
    $mgmt = gwmi -n root\virtualization\v2 -class Msvm_VirtualSystemManagementService -ComputerName $hvServer
    if(-not $mgmt)
    {
        return $false
    }

    #
    # Setting the new MMIO gap size
    #
    $vssd.LowMmioGapSize = $newGapSize

    $sts = $mgmt.ModifySystemSettings($vssd.gettext(1))

       if ($sts.ReturnValue -eq 0)
    {
        return $true
    }

    return $false
}

The location of the MMIO gap can be verified by searching the keyword “pci_bus” in the post boot dmesg log of the Linux virtual machine. This output containing the keyword should provide the start memory address of the MMIO gap. The size of the MMIO gap can then be verified by subtracting the start address from 4GB represented in hexadecimal.

Summary

Over the past year, the LIS team added a slew of features to enable great support for Linux virtual machines running on Hyper-V. These features will not only simplify the process of hosting Linux on Hyper-V but will also provide superior consolidation and improved performance for Linux workloads. As of now the team is actively working with various Linux vendors to bring these features in newer distribution releases. The team is eager to hear customer feedback and invites any feature proposals that will help improve Linux hosters experience on Hyper-V. Customers may get in touch with the team through linuxic@microsoft.com or thorough the Linux Kernel Mailing List (https://lkml.org/).

To see all of the posts in this series, check out the What’s New in Windows Server & System Center 2012 R2 archive

16 Dec 15:00

PowerTip: Use PowerShell to Find Connections to Remote Servers

by The Scripting Guys

Summary: Use Windows PowerShell to find connections to remote servers.

Hey, Scripting Guy! Question How can I use Windows PowerShell while I am troubleshooting my computer to find what
          connections are made to remote servers via port 80?

Hey, Scripting Guy! Answer Use the Get-NetTCPConnection command, specify the remote port of 80, and select the remote addresses:

Get-NetTCPConnection -RemotePort 80 | SELECT RemoteAddress

11 Dec 14:12

Weekend Scripter: Who are the Administrators?

by The Scripting Guys

Summary: Guest blogger, Bill Stewart, talks about using Windows PowerShell to find administrators.

Microsoft Scripting Guy, Ed Wilson, is here. Hello everyone. It is the weekend, and guest blogger, Bill Stewart is going to share his time and knowledge today. Bill is a scripting guru and a moderator for the Official Scripting Guys Forum...

As you know, an administrator of a Windows computer is a member of the computer’s local Administrators group. This is a special built-in group, so any user or group that’s a member of this special group is an administrator on the computer. We can see who the members of this group are by typing the command net localgroup Administrators at a cmd.exe or Windows PowerShell prompt.

Get local group membership by using ADSI

But what if we want to get the members of the local Administrators group on a remote computer? We can’t use the net localgroup command because it works only on the local computer. Since we’re talking Windows  PowerShell, you might be aware that you can use the [ADSI] type accelerator to connect to a group on a computer; for example:

$localAdminGroup = [ADSI] "WinNT://remotecomputer/Administrators,Group"

This creates a System.DirectoryServices.DirectoryEntry object that references the local Administrators group on the computer RemoteComputer. This is an object, so we should be able to call its Members method to view the members of the group:

$localAdminGroup.Members()

However, this produces some peculiar output:

System.__ComObject

...

The members of the group are COM objects, but Windows PowerShell doesn’t know what to do with them because there’s no type library that tells Windows PowerShell the interface for the objects (that is, what the properties and methods are). The workaround is to call the InvokeMember method of each COM object’s base type to retrieve the name property, like this:

$localAdminGroup.Members() | ForEach-Object {

  $_.GetType().InvokeMember("Name", "GetProperty", $NULL, $_, $NULL)

}

It’s ugly, but it works. But we have another issue. What if you’re using a non-English version of Windows? Or what if the Administrators group has been renamed? In either case, the ADSI technique isn’t going to work because the group might not be named Administrators.

Get Administrators group name by using WMI

The alternative is to use WMI. By using WMI, we can ask for the group by its SID, S-1-5-32-544, rather than by its name:

Get-WMIObject -Class Win32_Group `

  -Filter "LocalAccount=TRUE and SID='S-1-5-32-544'" `

  -Computer remotecomputer

This gives us output like this:

Caption                        Domain          Name            SID

-------                        ------          ----            ---

REMOTECOMPUTER\Administrators  REMOTECOMPUTER  Administrators  S-1-5-32-544

Get-WMIObject supports credentials, so if you’re signed in with an account that doesn’t have permission to access the remote computer, you can create a credential object to make the connection:

$credential = Get-Credential

Get-WMIObject -Class Win32_Group `

  -Filter "LocalAccount=TRUE and SID='S-1-5-32-544'" `

  -ComputerName remotecomputer `

  -Credential $credential

Combine ADSI and WMI?

Now that we’ve connected to the actual Administrators group, we can use the Name property, with ADSI and script in the previous section, to get the members of the group:

$credential = Get-Credential

$computerName = "remotecomputer"

$wmiObject = Get-WMIObject `

  -Class Win32_Group `

  -Filter "LocalAccount=TRUE and SID='S-1-5-32-544'" `

  -ComputerName $computerName `

  -Credential $credential

$adminGroupName = $wmiObject.Name

$adminGroup = [ADSI] "WinNT://$computerName/$adminGroupName,Group"

$adminGroup.Members() | ForEach-Object {

  $_.GetType().InvokeMember("Name", "GetProperty", $NULL, $_, $NULL)

}

Now we’re getting somewhere. The output of this script is a list of names like this:

Administrator

Domain Admins

kendyer

...

This is good, but we’re missing something. We know that Administrator is probably a local account and Domain Admins is probably a domain group. But we don’t know if kendyer is a local account or a domain account. To avoid confusion, it would be really helpful if the output contained the domain name for domain accounts.

Also, there’s another issue with this approach: It’s relatively inefficient. We’re making an initial WMI connection to the remote computer to retrieve the Administrators group name, and then we’re making a second connection (connecting to the ADSI group object) to retrieve the group members. This may not be an issue on a fast network, but over slower connections, it doesn’t scale very well.

Use WMI to get members

To avoid making two separate connections to each remote computer, we can stick with WMI. When we connect to a computer and retrieve its Administrators group, we’re retrieving a .NET ManagementObject object:

$credential = Get-Credential

$computerName = "remotecomputer"

$wmiObject = Get-WMIObject `

  -Class Win32_Group `

  -Filter "LocalAccount=TRUE and SID='S-1-5-32-544'" `

  -ComputerName $computerName `

  -Credential $credential

".NET object type: {0}" -f $wmiObject.GetType().FullName

"WMI class: {0}" -f $wmiObject.__CLASS

The output of this command is:

.NET object type: System.Management.ManagementObject

WMI class: Win32_Group

WMI objects can be related to each other by using associator classes; in this case, WMI relates the Win32_Group class with its members by using the Win32_GroupUser associator class. The WMI GetRelated method can use the Win32_GroupUser class to retrieve the group’s members, like this:

$credential = Get-Credential

$computerName = "remotecomputer"

$wmiObject = Get-WMIObject `

  -Class Win32_Group `

  -Filter "LocalAccount=TRUE and SID='S-1-5-32-544'" `

  -ComputerName $computerName `

  -Credential $credential

$wmiObject.GetRelated("Win32_Account")

When I run this on my computer, though, the script seems to hang, and it never finishes. There are simply too many relationships in WMI for this call to the GetRelated method to complete in a reasonable amount of time. To get around this issue, I need to specify the parameters to the GetRelated method to tell WMI that I only want the members of this specific group—not every possible relationship:

$credential = Get-Credential

$computerName = "remotecomputer"

$wmiObject = Get-WMIObject `

  -Class Win32_Group `

  -Filter "LocalAccount=TRUE and SID='S-1-5-32-544'" `

  -ComputerName $computerName `

  -Credential $credential

$wmiObject.GetRelated("Win32_Account","Win32_GroupUser","","",

  "PartComponent","GroupComponent",$FALSE,$NULL)

In this case, I use all eight parameters for the GetRelated method to focus on the exact relationship between the Win32_Group object instance (in the variable $wmiObject) and its related Win32_Account object instances. When I run the previous script, I get the desired output:

AccountType : 512

Caption     : REMOTECOMPUTER\Administrator

Domain      : REMOTECOMPUTER

SID         : S-1-5-21...

FullName    :

Name        : Administrator

Caption : FABRIKAM\Domain Admins

Domain  : FABRIKAM

Name    : Domain Admins

SID     : S-1-5-21...

Improve WMI performance

I’ve run into a final snag, though. When I connect to a remote computer over a slow network connection, I get the group members, but the GetRelated method only outputs one group member at a time. To speed things up, I would prefer to retrieve multiple members at a time; say, in batches of 50 members.

To do this, I need to create a System.Management.EnumerationOptions object, set its BlockSize property to 50, and use this object as the final parameter of the GetRelated method:

$wmiEnumOpts = new-object System.Management.EnumerationOptions

$wmiEnumOpts.BlockSize = 50

$credential = Get-Credential

$computerName = "remotecomputer"

$wmiObject = Get-WMIObject `

  -Class Win32_Group `

  -Filter "LocalAccount=TRUE and SID='S-1-5-32-544'" `

  -ComputerName $computerName `

  -Credential $credential

$wmiObject.GetRelated("Win32_Account","Win32_GroupUser","","",

  "PartComponent","GroupComponent",$FALSE,$wmiEnumOpts)

Now, I get the same output, but it runs faster because the GetRelated method retrieves the local Administrator group’s membership in batches of 50 instead of one at a time.

User friendly output

When I use the GetRelated method, the object instances are output by the default formatter in Windows PowerShell. These output objects provide a lot of detail, but I only want to know three things:

  • The computer name where the local Administrators group resides
  • The name of the Administrators group (in case it’s not in English or has been renamed)
  • The name of the member of the group

To do this, I’ll use the Select-Object cmdlet to output customized objects that contain only the information I want:

$wmiEnumOpts = new-object System.Management.EnumerationOptions

$wmiEnumOpts.BlockSize = 20

$credential = Get-Credential

$computerName = "remotecomputer"

$wmiObject = Get-WMIObject `

  -Class Win32_Group `

  -Filter "LocalAccount=TRUE and SID='S-1-5-32-544'" `

  -ComputerName $computerName `

  -Credential $credential

$groupName = $wmiObject.Name

$wmiObject.GetRelated("Win32_Account","Win32_GroupUser","","",

  "PartComponent","GroupComponent",$FALSE,$wmiEnumOpts) |

  Select-Object `

  @{Name="ComputerName"; Expression={$_.__SERVER}},

  @{Name="Name"; Expression={$groupName}},

  @{Name="Member"; Expression={$_.Caption}}

Note that I’m retrieving the group’s name before calling the GetRelated method so I can include it in the output objects.

There is one final “tweak” I want to include. If the account is a local account, I want to omit the computer name from the Member output property; that is, I want my Member property to contain Administrator rather than RemoteComputer\Administrator. To get this effect, I’ll use the Windows PowerShell -replace operator to replace the computer name from the Caption property with an empty string. To do this, let’s replace the final line of script:

@{Name="Member"; Expression={$_.Caption}}

with this instead:

@{Name="Member"; Expression={$_.Caption -replace "^$($_.__SERVER)\\", ""}}

This code gives me the final output I want:

ComputerName    Name            Member

------------    ----            ------

REMOTECOMPUTER  Administrators  Administrator

REMOTECOMPUTER  Administrators  D1\Domain Admins

...

Put it all together

Now that we have the working script, all that’s left is to put it together so it’s easy to use. You can download the entire script from the TechNet Gallery, and it supports pipeline input for computer names: Get-LocalAdminGroupMember.ps1.

~Bill

Thanks Bill. Excellent post.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

10 Dec 17:27

How to Deploy and Discover Windows PowerShell Desired State Configuration Resources

by PowerShell Team

A Windows PowerShell Desired State Configuration (DSC) resource contains a module file (*.psm1), an optional data file (*.psd1),and a *.schema.mof file. Details about what each of those files should look like, and how you can create those files using a DSC Resource Designer Tool, are discussed in an earlier blog post.  In this blog post, we will explore the following.

  1. How to deploy DSC resources to the local computer
  2. How to discover the resources deployed, while authoring a new configuration
  3. How to deploy resources to the pull server, and how the local configuration manager (LCM) locates the required resources on the pull server.

Deploying DSC resources to the local computer

All DSC resources should be deployed in the following folder hierarchy:-

            $env: psmodulepath (folder)

                        |- <ModuleName> (folder)

                                    |- DSCResources (folder)

                                                |- <DSCResourceName1> (folder)

                                                            |- <DSCResourceName1.psd1> (file, optional)

                                                            |- <DSCResourceName1.psm1> (file, required)

                                                            |- <DSCResourceName1.schema.mof> (file, required)

                                                |- <DSCResourceName2>(folder)

                                                             |- <DSCResourceName2.psd1> (file, optional)

                                                             |- <DSCResourceName2.psm1> (file, required)

                                                             |- <DSCResourceName2.schema.mof> (file, required)          

                      

Example:  Suppose the Hyper-V team decided to add a resource named VM in to their existing PowerShell module under $pshome, Then the folder structure of their DSC resource would look like the following.

 

C:\Windows\system32\WindowsPowerShell\v1.0\Modules\Hyper-V\DSCResources\VM\                                                                                     -VM.psd1(optional)                                                                                                                                                            -VM.psm1                                                                                                                                                                   -VM.Schema.mof

 

Usually, the environment variable $env:psmodulePath contains more than one path, and you can deploy DSC resources in any one of the paths. But there are some subtle differences during authoring or applying configuration to the system. Because LCM runs in System context, applying a configuration fails if your resources module are not in the $pshome or $env:ProgramFiles folder. The differences in the authoring experience are discussed in this post, in the Import-DSCResources section.

How to use and discover DSC resources

The number of PowerShell modules and cmdlets are increasing in every PowerShell release, hence increasing the number of results returned by Get-Module and Get-Command.  To keep those cmdlets useful, DSC resources have been stored in a subfolder of a main PowerShell module folder.

 

Because DSC Resources are not deployed directly under $env: psmodulepath, they cannot be discovered by running the Get-Module -List Available cmdlet. Get-Command for the GET/SET/TEST method of the resources will fail. Also, you can’t import the DSC resource with a partial name, as shown in the following examples.

Let us try to find MSFT_EnvironmentResource, one of the DSC resources which is shipped with PowerShell 4.0.

 

Get-Module MSFT_EnvironmentResource –ListAvailable   # Empty result (module not found)

Get-Command Get-TargetResource # Error: Command not found exception.

Import-Module MSFT_EnvironmentResource # Error: ModuleNotFound

 

You can, however, import the module by using its full path, like any PowerShell module, and call its GET/SET/TEST methods.

Import-Module C:\Windows\System32\WindowsPowerShell\v1.0\Modules\PSDesiredStateConfiguration\DSCResources\MSFT_EnvironmentResource # Works

 

There are two new cmdlets that are added in PowerShell 4.0 to help discover DSC resources.

 

Get-DscResource: Gets all the DSC resources. You can pass a resource name list to filter the result.

                    Example:-Get-DscResource Env*ment, Windows*, Log   ß Returns all the resources that match the specified criteria.

So one way to test if your resources are deployed correctly is to see if they are being discovered by Get-DscResource.

 

Import-DscResource:  Import-DScResource is a dynamic keyword which can only be used inside a Configuration script block. When you are authoring a new configuration, you must import the resources needed by your configuration using this cmdlet. But if your DSC resources are stored in $pshome, you don’t need to explicitly import them. They are automatically loaded by PowerShell.

The signature of the cmdlet is shown below.

Import-DscResource [-Name <ResourceName(s)>] [-ModuleName <ModuleName(s)>]

Name:  This is the DSC resource name(s) that you must import. If the module name is specified, the command searches for these DSC resources within this module; otherwise the command searches the DSC resources in all DSC resource paths.

ModuleName:  This is the container module name(s), or module specification(s).  If the DSC resources that are required are specified, the command will try to import only those resources from the module(s).; Otherwise, the command imports all  the DSC resources in this module.

You can specify either one or both Name and ModuleName parameters in the cmdlet. But you must explicitly pass pairs of the parameter name and its value. Positional parameters are not supported.

            Import-DscResource is a second way to make sure your resources are deployed correctly.

Example:-

Configuration MSDSCConfiguration  {

                                       

Import-DSCResource -ModuleName MS_DSC1 -name Resource1, Resource2, Resource3

# Search for and imports Resource1 Resource2, and Resource3 inside the modules MS_DSC1

Import-DSCResource -Name Resource1 

# Search DSC resources for Resource1 under all valid DSC resource paths, and import the

# resource. Note that this will run slower because it has to search the resource in all the

# valid DSC resource folders. 

Import-DSCResource -ModuleName MS_DSC1

# Search for and import all DSC resources inside the module MS_DSC1. 

  ...

}

Deploying DSC resources to the pull server

After you configure your pull server [For details about how to configure a pull server, and how a pull client works, see this blog post]. DSC resources can be packaged and placed in the pull server resource repository for pull clients to download it. The folder hierarchy of the pull server DSC Resource repository should be the following. 

$env:ProgramFiles\WindowsPowerShell\DscService\Modules\  (folder)                                                                                        ModuleName_Version.zip                                                                                                             ModuleName_Version.zip.checksum 

When it’s unzipped, ModuleName_Version.zip should have the same folder structure as the local computer deployment hierarchy shown at the beginning of this blog post.

  • The Version is the version of the module, not the version of the DSC resource. Versioning works at the module level, not the DSC resource level.
  • ModuleName_Version.zip. Checksum is a checksum of the zip file generated by running the following  command.

New-DSCCheckSum –path $env:ProgramFiles\WindowsPowerShell\DscService\Modules\ -force

 

A configuration stored in the pull server configuration repository that requires the preceding module must refer to the module as follows.

 

instance of <ResourceName>

{

….  

ModuleName = "<ModuleName>";

ModuleVersion = “<Version>"; 

};

 

After LCM downloads a configuration from the pull server, it checks if the resources needed by the configuration exists on the local machine. If it does not exist, LCM queries the Download Manager of the local machine to download the required module, by specifying the ModuleName and ModuleVersion. After the module is downloaded and verified, it is saved to the $env: ProgramFiles\WindowsPowershell\Modules\ folder, and the configuration is applied by calling the TEST and SET methods of each resources.

 

 

 

 

 

Berhe Abrha

PowerShell Team

10 Dec 14:19

Administrative Templates (.admx) for Windows 8.1 and Windows Server 2012 R2 | CryptoLocker defense for sysadmins

by Michael Pietroforte
A picture of Michael PietroforteMVP

Michael Pietroforte - 0 comments

Michael Pietroforte is a Microsoft Most Valuable Professional (MVP) with more than 30 years of experience in system administration.

  • Administrative Templates (.admx) for Windows 8.1 and Windows Server 2012 R2 link
  • CryptoLocker Defense for Sysadmins link

Copyright © 2006-2013, 4sysops, Digital fingerprint: 3db371642e7c3f4fe3ee9d5cf7666eb0

09 Dec 14:19

Free e-learning course - VMware vSphere 5.5 What’s New

by nospam@example.com (Eric Sloof)
VMware vSphere 5.5 introduces many new features and enhancements to further extend the core capabilities of the vSphere platform. This E-Learning will discuss features and capabilities of the vSphere platform, including vSphere ESXi Hypervisor, VMware vSphere High Availability (vSphere HA), virtual machines, VMware vCenter Server, storage networking and vSphere Big Data Extensions.


06 Dec 16:30

Fix: Class not registered Chrome.exe in Windows 8

by AnandK@TWC
Class not registered Chrome.exe

If you click on your Google Chrome browser’s tile on Windows 8 Start Screen or any shortcut and find that Chrome browser will not open, then this post will surely interest you. Specifically, you may also receive the Class not [...]

This post Fix: Class not registered Chrome.exe in Windows 8 is from TheWindowsClub.com.

06 Dec 13:45

Creating PowerShell ISE v3 (and later) Code Snippets

by Jonathan Medd

When using the PowerShell ISE , similar to other scripting editors, you have access to what are known as ‘code snippets’. These are quick start ways to generate frequently used code, for instance if there is something you use regularly and can never remember the syntax for, or maybe it is too long to be practical to remember it.

PowerShell ships with some default snippets and it is also possible to add some custom snippets of your own. They can be accessed via the keyboard shortcut Ctrl-J - the below screenshot displays the default snippets available.

ISESnippet01

Selecting one of these snippets will populate the editor with the sample code. In the example below I picked the switch snippet, not one that’s always easy to remember, and an example is placed in the editor which I can modify for my needs.

ISESnippet02

Naturally, you may want to create some of your own, known as User-Defined Snippets. PowerShell v3 ships with some cmdlets to help you create and manage these, starting with the New-ISESnippet cmdlet. Give the code you wish to use for your snippet to this cmdlet and it will create a <Title>.Snippets.ps1xml file in the $home\Documents\WindowsPowerShell\Snippets directory with the title that you specify .

For example, one thing that students in the PowerShell classes I teach often struggle to remember is the syntax for creating a calculated property with Select-Object, like say this:

Get-ChildItem C:\Test | Select-Object Name, CreationTime,  @{N="Kbytes";E={$_.Length / 1Kb}}

So, we can create a snippet to help with this via the following (Note, the CaretOffset parameter places the cursor in a specific place after using the snippet, in this case at the start of the word ‘Title’ that you need to edit. Aren’t I helpful?!):


New-IseSnippet -Title "Calculated Property" -Description "Syntax for a Calculated Property" -Text "@{N='Title';E={ }}" -CaretOffset 5

This will create the below XML file in my  snippets folder for both current and future use every time I open the PowerShell ISE.

ISESnippet03

Now if I get to a point where I can’t remember the syntax for a calculated property….

ISESnippet04

I can select the snippet and have it populate that difficult to remember syntax for me:

ISESnippet05

ISESnippet06

So that is cool for short syntax items, but what about something which is multiline, how would I create a snippet for that? One answer is to use a Here-String.

For example, say you wish to add a parameter block like this as a snippet


Param
 (

[parameter(Mandatory=$true,ValueFromPipeline=$true)]
 [ValidateNotNullOrEmpty()]
 [String[]]$Parameter1,

 [parameter(Mandatory=$false,ValueFromPipeline=$false)]
 [ValidateNotNullOrEmpty()]
 [PSObject[]]$Parameter2
 )

First of all store this text in a Here-String then use that Here-String with New-ISESnippet . Tip: ensure you use single quotes rather than double to create the Here-String otherwise the variables will be expanded to blank, since they (probably) don’t exist.


$Snippet = @'
 Param
 (

[parameter(Mandatory=$true,ValueFromPipeline=$true)]
 [ValidateNotNullOrEmpty()]
 [String[]]$Parameter1,


 [parameter(Mandatory=$false,ValueFromPipeline=$false)]
 [ValidateNotNullOrEmpty()]
 [PSObject[]]$Parameter2
 )
'@

New-IseSnippet -Title "Param Block" -Description "Syntax for a Param Block" -Text $Snippet

Now I can create a Param Block with this multiline snippet

ISESnippet07

ISESnippet08

and our snippets folder contains two XML files, one for each snippet:

ISESnippet09

Having multiple snippet files may or my not be a good thing, depending on your scenario. It’s possible if you want to share these that you may want to combine them into a single file. This post on the PowerShell team blog details an XML snippet example and its structure. If we take the content between <Snippet Version=’1.0.0′> and </Snippet> we can combine each snippet into one file which is maybe easier for distribution to others if you want them to have all of those snippets.

ISESnippet10

Next week I’ll be posting some snippets that are part of my UKVMUG session which you may find useful, all combined into one file…….

29 Nov 14:13

WinSxS Folder Cleanup – Regain disk space in Windows 7

by Jim Jones
A picture of Jim Jones

Jim Jones - 0 comments

Jim Jones has been a Windows/Network/Voice Systems administrator for over a decade and currently works as a Sr. Network Administrator in West Virginia, USA. Jim can be found on Twitter @k00laidIT.

The WinSxS Folder Cleanup wizard allows you to regain a significant amount of disk space in Windows 7.

If you are like me and started your time with Windows back in the olden days (you know, before XP) you have probably noticed Windows now has a tendency to bloat badly over time. Further examination within the Windows directory will lead you to take a look at the WinSxS folder under C:\Windows, also known as the component store directory.

As an example as I write this article this directory on my test VM is currently at 17.1 GB, which is a bit much. Even worse, trying to manually just dump this directory will severely break your Windows installation. Well after a new patch released with the October batch, KB2852386, we now have a method to clean up unused updates in this directory and help to bring Windows back down to its fighting weight.

WinSXS folder size

WinSXS folder size

… read more of WinSxS Folder Cleanup – Regain disk space in Windows 7

Copyright © 2006-2013, 4sysops, Digital fingerprint: 3db371642e7c3f4fe3ee9d5cf7666eb0


Related
26 Nov 15:07

Managing VMware with CIM and PowerShell

by Jeff Hicks

In PowerShell 3.0, Microsoft introduced the Common Information Model (CIM) cmdlets as a way of working with WMI information. The advantage was that instead of connecting to WMI over RPC and DCOM, which is not very firewall-friendly, we can connect using the WSMan protocol, delivered by the WinRM service which uses only a couple ports. Here’s the best part and why you should be learning to how to use the CIM cmdlets: You can connect to any device or server that supports WSMan and CIM. This includes a VMware ESXi server.

Manage VMware with CIM: Connect to WSMan

What I’m going to demonstrate does not use any of the PowerCLI cmdlets. Instead, you can use existing CIM cmdlets in PowerShell 3.0. I will warn you up front that getting WMI information from a VMware server is not easy or obvious. Depending on your server and network configuration, your experience might be quite different and could entail a bit of research and a lot of trial and error.

To begin, I’m going to create a CIM session object to my ESXi server. Because my server does not use Active Directory for authentication, nor is it configured with an appropriate certificate, I’ll need to set some options for my CIM session.

PS C:\> $CIMOpt = New-CimSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck -Encoding Utf8 –UseSsl

If you can’t establish a CIM session outright, you might need to experiment with different options. Although I suspect at a minimum you will need to set encoding and use SSL.

To create my session, I will need to authenticate.

PS C:\> $HostUsername = Get-Credential root

Now to create my session.

PS C:\> $Session = New-CimSession -Authentication Basic -Credential $HostUsername -ComputerName "esx.jdhitsolutions.local" -port 443 -SessionOption $CIMOpt

PS C:\> $session

Id           : 2

Name         : CimSession2

InstanceId   : 645a6236-4f10-485a-89c3-4e2c01bda1ca

ComputerName : esx.jdhitsolutions.local

Protocol     : WSMAN

Unfortunately, you can’t use Test-WSMan with the VMware host.

CIM Classes

I’m assuming that when the VMware server was installed, nobody skipped the option to enable WMI and CIM support. If you did, then none of what I’m showing you will work. But assuming you are ready to go, all that remains is to query a class.

The default namespace is root/cimv2. However, enumerating classes is almost next to impossible using the existing CIM cmdlets. In fact, the only cmdlet that seems to work reliably well is Get-CimInstance. I think you will find it easiest to research the class names ahead of time, although I’ll demonstrate a few in a bit. The best place to start is in the vSphere documentation.

Even though you will see things like OMC and VMWare, these are extensions of the parent CIM classes, which from what I can tell are the only ones you can query using Get-CimInstance. It might be possible to get more granular using the winrm command-line tool, but that is going to be much more complicated. Be aware that even though you see a CIM class listed in the online documentation, there’s no guarantee you will get any instances of that class. Again, there is a lot of trial and error here.

Querying CIM

Using the established CIM session, querying the VMware server in some ways is not that much different than querying a Windows server.

PS C:\> $session | Get-CimInstance CIM_ComputerSystem

You can see my result in Figure 1.

Manage VMware with CIM

 

An important note: the class names are case-sensitive. Typically CIM_ and then the remainder in camel case. Use whatever format you see in the online documentation.

Querying this class actually results in two instances, which are the derived OMC classes.

PS C:\> $session | Get-CimInstance CIM_ComputerSystem | Select CreationClassName

CreationClassName

-----------------

OMC_ModularComputerSystem

OMC_UnitaryComputerSystem

You will see this behavior often.

Another useful query might be to get processor information.

Manage VMware with CIM processor information

Or Ethernet port.

PS C:\> $session | Get-CimInstance CIM_EthernetPort

Manage VMware with CIM ethernet port

You will find a number of elements bundled together by a parent CIM class, which is often the easiest way to gather information or at least discover class names that you can use for a more refined command.

Manage VMware with CIM

PS C:\> $le.name

System BIOS

VMware ESXi

VMware ESXi Alternate Boot Bank

EVAL

c015a0c5-b3a1-db11-8d9f-001a923ac60b

MAP

vmk0

vmk0

Cache memory

Cache memory

System Memory

20202020202020202020202036514630465A5159

20202020202020202020202036514630425A3858

Unknown

Unknown

vmnic0

VMware:HostPowerManagement

SoftwareInstallationService

VMware_KernelModuleService

Unfortunately, you can’t simply create a WMI filter. A command like this will fail.

PS C:\> $session | Get-CimInstance CIM_LogicalElement -filter "name = 'System BIOS'"

It seems your best bet for now is to get everything and then pipe to Where-Object.

PS C:\> $le | where {$_.name -eq 'System Bios'}

If you want to identify all managed elements, use a command like this:

PS C:\> $cms = Get-CimInstance -CimSession $Session -ClassName CIM_ManagedSystemElement

This should include everything that was part of CIM_LogicalElement. Then use PowerShell to get what you want. Here’s a slightly complicated example to retrieve software information from my ESXi server.

$cms | where name -eq 'vmware esxi' |

Select Name,VersionString,

@{Name="ReleaseDate";Expression={[System.Management.ManagementDateTimeConverter]::ToDateTime( $_.ReleaseDate)}},

@{Name="LastStartTime";Expression={[System.Management.ManagementDateTimeConverter]::ToDateTime( $_.LastStartTime)}},

@{Name="Uptime";Expression={(Get-Date) - [System.Management.ManagementDateTimeConverter]::ToDateTime( $_.LastStartTime)}},

PSComputername

The date values are still in the DMTF format, so I convert them to something easier to read and also calculate an uptime. When I execute this code in my PowerShell 3 session I get a result like this.

Name           : VMware ESXi

VersionString  : 5.1.0 build-799733

ReleaseDate    : 7/31/2012 8:00:00 PM

LastStartTime  : 10/30/2013 2:49:02 PM

Uptime         : 8.23:31:56.7340940

PSComputerName : esx.jdhitsolutions.local

Once you know what you want, it wouldn’t take that much more work to turn your command into easy to use PowerShell tools and functions.

The promise of one management tool for everything, regardless of platform, is very tantalizing. Learning how to manage your VMware servers with CIM and PowerShell would be a good place to start. Just be prepared for a lot of trial and error and experimentation, and if you have successes, I hope you‘ll share them with the community.

26 Nov 14:26

PowerShell DSC Resource for configuring Pull Server environment

by PowerShell Team


DSC
is a PowerShell extension that is part of Windows Server 2012 R2 and Windows 8.1. DSC enables deploying and managing configuration data for software services and managing the environment in which these services run.

A DSC Pull Server is a web-based endpoint, with an OData interface. This server allows nodes to “Pull” Configuration such as providers on a periodic basis. This functionality is useful in environments where there are a large number of target nodes to configure, and where the target nodes need the right configuration as they come online, and to check periodically for configuration updates.

The “Pull” mechanism is a highly scalable mechanism to deploy specific environments on machines.

 

 

This blog is about the process of setting up a Pull Server using a DSC configuration.

 

DSC Configuration and Resource:

The following configuration enables to setup a Pull/Compliance Server at a specified IIS endpoint (Port/Web-Site Name).
There is capability to setup HTTP/HTTPS based endpoints.

 

 

 

 

MOF for the DSC Resource:

 

 

 

Module that implements the DSC *-TargetResource cmdlets:

 

 

 

Module for setting up a Management OData (PSWS) IIS Endpoint – Required for Pull Server:

 

STEPS:

Here is a walkthrough of setting up a Pull Server on a Windows Server machine.

1)      Unzip DSCPullServerConfiguration.zip to $env:systemdrive

2)      Deploy DSC Resources (module that implements DSC *-TargetResource cmdlets, MOF etc) to Program Files

 

3)      Run the configuration to setup Pull and Compliance Server OData-IIS endpoints

(Note: This sample generates a self-signed cert –using makecert.exe for the HTTPS endpoint)

 

4)      Navigate to the Pull Server OData IIS endpoint

 

 

That’s it! Your Pull Server is ready for use.

 

Updated on 12/27/2013: Removing the older version of resource. For most recent version, go here


Thanks,
Raghu Shantha [MSFT]

PowerShell Team

 

 

21 Nov 13:52

Enabling Email Signatures with Office 365–a PowerShell Solution

by Thomas Lee
Like many folks, I use Outlook pretty much exclusively for my email. One nice feature is the ability to set a ‘signature’, text that is added to the bottom of each email I author and send. The signature can contain pretty much anything you want , including your phone numbers, your Lync ID, etc.
Ben Norcutt has just published a nice article on how you can use PowerShell to set email signatures with Office 365. You can see the article and the PowerShell scripts here: http://4sysops.com/archives/add-a-signature-to-office-365-emails-with-powershell/
Technorati Tags: PowerShell,Office 365,signature
20 Nov 15:23

Resource Designer Tool – A walkthrough writing a DSC resource

by PowerShell Team

At the heart of Windows PowerShell Desired State Configuration are the resources. It is the resources which act behind the scenes for DSC to achieve its “make it so” philosophy. DSC ships with a number of resources in-box and you can take a look here for the complete list. However, once you get started with DSC, you may want to write your own resources (which are PowerShell modules) for your particular use case. This post will walk you through creating a custom DSC resource. You can take a look here to get an understanding of the schema/packaging of DSC resources. Attached with this post is the Resource Designer Tool which makes writing resources a breeze.

There are certain rules which must be complied with when writing a DSC resource. I will state the rules towards the end of the post for reference and completeness. The Resource Designer Tool takes care of the nitty-gritty so that you can concentrate on implementing the features in your resource without having to get caught up in figuring out the correct MOF syntax or worrying about missing some important requirements in the resources (which is a PowerShell module) file.

Let us take an example. Say you want to create a resource for modelling an Active Directory User. (The User resource shipped in-box is for local users only.) In this example, we will have the following configuration properties in our schema MOF:

  • UserName -> This will be the key property for our resource to uniquely identify a user. This is a required property
  • Ensure -> This can only take two values: ‘Present’ and ‘Absent’ for stating whether we want the user account to be present or absent.
  • DomainAdminCredential -> This will hold the domain account password for the user.
  • Password -> This will hold the new password in case we wish to change an existing password.

Once we have the properties all set out, we can begin using the Resource Designer Tool. For this, create a folder named ‘DSCPack_ResourceDesigner’ anywhere inside your $env:PSModulePath, download the attachments and place them inside the folder you just created. After this, import the module (using ‘Import-Module DSCPack_ResourceDesigner’). We are all set. Let’s dive in now!

Let us see all the commands which we have as part of the designer tool:

PS C:\> (Get-Module DSCPack_ResourceDesigner).ExportedCommands

 

Key                                                      Value                                                 

---                                                      -----                                                 

Import-DscSchema                                         Import-DscSchema                                     

New-DscResource                                          New-DscResource                                      

New-DscResourceProperty                                  New-DscResourceProperty                              

Test-DscResource                                         Test-DscResource                                      

Test-DscSchema                                           Test-DscSchema                                       

Update-DscResource                                       Update-DscResource                                    

 

The first cmdlet we will be using is New-DscResourceProperty. Let us explore it.

PS C:\> help New-DscResourceProperty

 

NAME

    New-DscResourceProperty

   

SYNOPSIS

    Creates a DscResourceProperty to be used by New-DscResource.

   

   

SYNTAX

    New-DscResourceProperty [-Name] <String> [-Type]< String> [-Attribute] {Key | Required | Read | Write}

    [-ValidateSet <String[]>] [-Description <String>] [<CommonParameters>]

   

   

DESCRIPTION

    Takes all of the given arguments and constructs a DscResourceProperty object to be used by New-DscResource.

   

 

RELATED LINKS

 

REMARKS

    To see the examples, type: "get-help New-DscResourceProperty -examples".

    For more information, type: "get-help New-DscResourceProperty -detailed".

    For technical information, type: "get-help New-DscResourceProperty -full".

 

For every configuration property we want, we need to define it using this cmdlet. Let us see how we would define the various properties we stated earlier:

UserName:

PS C:\> $UserName = New-DscResourceProperty -Name UserName -Type String -Attribute Key

 

Ensure:

PS C:\> $Ensure = New-DscResourceProperty -Name Ensure -Type String -Attribute Write -ValidateSet "Present", "Absent" 

 

DomainCredential:

PS C:\> $DomainCredential = New-DscResourceProperty -Name DomainAdminCredential -Type PSCredential -Attribute Write

 

Password:

PS C:\> $Password = New-DscResourceProperty -Name Password -Type PSCredential -Attribute Write

 

Now that the properties are defined, let us see how to generate the PowerShell module that will contain the implementation logic of the resource and the schema MOF file which will be consumed by DSC. The cmdlet we are looking for is New-DscResource.

PS C:\> help New-DscResource

 

NAME

    New-DscResource

   

SYNOPSIS

    Creates a DscResource based on the given arguments.

   

   

SYNTAX

    New-DscResource [-Name] <String> [-Properties] <DscResourceProperty[]> [-Path] <String> [-ClassVersion< Version>] [-FriendlyName

    <String>] [-Force] [-WhatIf] [-Confirm] [<CommonParameters>]

   

   

DESCRIPTION

    Creates a .psm1 and .schema.mof file representing a Dsc Resource based on the properties and values passed in.

   

 

RELATED LINKS

 

REMARKS

    To see the examples, type: "get-help New-DscResource -examples".

    For more information, type: "get-help New-DscResource -detailed".

    For technical information, type: "get-help New-DscResource -full".

 

 

Let us use the properties which we just defined to create the DSC resource.

PS C:\> New-DscResource -Name Demo_ADUser -Properties $UserName, $Ensure, $DomainCredential, $Password -Path 'C:\Program Files\WindowsPowerShell\Modules\DSCModules' 

 

 

Here is the output we get:

   Directory: C:\Program Files\WindowsPowerShell\Modules\DSCModules

 

 

Mode                LastWriteTime     Length Name                                                                                   

----                -------------     ------ ----                                                                                    

d----        11/13/2013   3:42 PM            DSCResources                                                                            

 

 

    Directory: C:\Program Files\WindowsPowerShell\Modules\DSCModules\DSCResources

 

 

Mode                LastWriteTime     Length Name                                                                                   

----                -------------     ------ ----                                                                                    

d----         11/13/2013   3:42 PM            Demo_ADUser                                    

 

 

 

Looks like something exciting is going on here. A directory for our custom DSC resource has been created. Let us peek into what is in there.

 

PS C:\> cd 'C:\Program Files\WindowsPowerShell\Modules\DSCModules\DSCResources\Demo_ADUser'

 

PS C:\Program Files\WindowsPowerShell\Modules\DSCModules\DSCResources\Demo_ADUser> dir

 

 

    Directory: C:\Program Files\WindowsPowerShell\Modules\DSCModules\DSCResources\Demo_ADUser

 

 

Mode                LastWriteTime     Length Name                                                                                   

----                -------------     ------ ----                                                                                    

-a---        11/13/2013   3:42 PM       3770 Demo_ADUser.psm1                                                                        

-a---        11/13/2013   3:42 PM        700 Demo_ADUser.schema.mof     

 

 

Let us take a look at the contents of the schema MOF:

 

[ClassVersion("1.0.0.0"), FriendlyName("Demo_ADUser")]

class Demo_ADUser : OMI_BaseResource

{

       [Key] String UserName;

       [Write, ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure;

       [Write, EmbeddedInstance("MSFT_Credential")] String DomainAdminCredential;

       [Write, EmbeddedInstance("MSFT_Credential")] String Password;

};

 

The designer tool took care of the syntax of the MOF file for us. One of the nice things I liked about the tool when I first started using it was that it took care of deriving the class from ‘OMI_BaseResource’. I would always forget about this. Also take note of how it converted ‘ValidateSet’ – a term well known to PowerShell scripters into ‘ValueMap’ – a term specific to CIM schema language specification. Similarly it knows to convert ‘PSCredential’ into the type ‘MSFT_Credential’ which is understood by the DSC Engine.

Next, let us see what the psm1 file looks like (As explained here, this file contains the three ‘*-Target-Resource’ functions):

function Get-TargetResource

{

       [CmdletBinding()]

       [OutputType([System.Collections.Hashtable])]

       param

       (

              [parameter(Mandatory = $true)]

              [System.String]

              $UserName

       )

 

       #Write-Verbose "Use this cmdlet to deliver information about command processing."

 

       #Write-Debug "Use this cmdlet to write debug information while troubleshooting."

 

 

       <#

       $returnValue = @{

              UserName = [System.String]

              Ensure = [System.String]

              DomainAdminCredential = [System.Management.Automation.PSCredential]

              Password = [System.Management.Automation.PSCredential]

       }

 

       $returnValue

       #>

}

 

 

function Set-TargetResource

{

       [CmdletBinding()]

       param

       (

              [parameter(Mandatory = $true)]

              [System.String]

              $UserName,

 

              [ValidateSet("Present","Absent")]

              [System.String]

              $Ensure,

 

              [System.Management.Automation.PSCredential]

              $DomainAdminCredential,

 

              [System.Management.Automation.PSCredential]

              $Password

       )

 

       #Write-Verbose "Use this cmdlet to deliver information about command processing."

 

       #Write-Debug "Use this cmdlet to write debug information while troubleshooting."

 

       #Include this line if the resource requires a system reboot.

       #$global:DSCMachineStatus = 1

 

 

}

 

 

function Test-TargetResource

{

       [CmdletBinding()]

       [OutputType([System.Boolean])]

       param

       (

              [parameter(Mandatory = $true)]

              [System.String]

              $UserName,

 

              [ValidateSet("Present","Absent")]

              [System.String]

              $Ensure,

 

              [System.Management.Automation.PSCredential]

              $DomainAdminCredential,

 

              [System.Management.Automation.PSCredential]

              $Password

       )

 

       #Write-Verbose "Use this cmdlet to deliver information about command processing."

 

       #Write-Debug "Use this cmdlet to write debug information while troubleshooting."

 

 

       <#

       $result = [System.Boolean]

      

       $result

       #>

}

 

 

Export-ModuleMember -Function *-TargetResource

 

 

This is the skeleton of the PowerShell Module generated by the tool. It contains the three functions that all DSC resources must define: Get-TargetResource, Test-TargetResource and Set-TargetResource. It also adds in some comments to help us with writing the resource. For example, take a look at the Test-TargetResource function. Since DSC is idempotent, we can apply the same configuration multiple times and if the current state is the same as the desired state, no action is taken. This is achieved by the DSC engine calling Set-TargetResource only if Test-TargetResource returns false. The tool hints at this by pointing out that Test-TargetResource should return a Boolean value. Also take note that the Get-TargetResource function contains the key property as its only parameter.

Given the skeleton of the generated module, we can proceed with adding our logic. After we are done writing our resource, we can see that it is one of the DSC resources added to the existing set:

PS C:\> Get-DscResource 'Demo_ADUser'

 

ImplementedAs   Name                      Module                         Properties              

-------------   ----                      ------                         ----------              

PowerShell      Demo_ADUser              DSCModules                     {UserName, …

 

 

At this point we can start writing our DSC configuration scripts using our new resource.

All this done, you realize you also need to add one more property which would be a hash table mapping a particular user to his last log in time.  Oh, no do you need to re write the entire resource again? No! We got you covered:

S C:\> help Update-DscResource

 

NAME

    Update-DscResource

   

SYNOPSIS

    Update an existing DscResource based on the given arguments.

   

   

SYNTAX

    Update-DscResource [-ModuleName]< String> [-Properties] <DscResourceProperty[]> [-ClassVersion

    <Version>] [-FriendlyName <String>] [-Force] [<CommonParameters>]

   

   

DESCRIPTION

    Update the .psm1 and .schema.mof file representing a Dsc Resource based on the properties and values

    passed in.

   

 

RELATED LINKS

 

REMARKS

    To see the examples, type: "get-help Update-DscResource -examples".

    For more information, type: "get-help Update-DscResource -detailed".

    For technical information, type: "get-help Update-DscResource -full".

 

So cool. Let us add the new property:

PS C:\> $lastLogOn = New-DscResourceProperty -Name LastLogOn -Type Hashtable -Attribute Write -Description "For mapping users to their last log on time"

 

Let us now update our resource:

PS C:\>  Update-DscResource -ModuleName 'Demo_ADUser' -Properties $UserName, $Ensure, $DomainCredential, $Password, $lastLogOn -Force

 

The contents of ADUser.schema.mof have been updated:

[ClassVersion("1.0.0.0"), FriendlyName("")]

class ADUser : OMI_BaseResource

{

       [Key] String UserName;

       [Write, ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure;

       [Write, EmbeddedInstance("MSFT_Credential")] String DomainAdminCredential;

       [Write, EmbeddedInstance("MSFT_Credential")] String Password;

       [Write, EmbeddedInstance("MSFT_KeyValuePair"), Description("For mapping users to their last log on time")] String LastLogOn;

};

 

 

If you take a look at the resource module, you will find that it has been updated too with the new parameter while all the logic you added are intact.

Let us cover one more cmdlet exposed by the designer tool:

PS C:\> help Test-DscSchema

 

NAME

    Test-DscSchema

   

SYNTAX

    Test-DscSchema [-Schema] <string> [[-SchemaCimClass]< ref>] [-errorIdsRef <ref>] 

    [<CommonParameters>]

   

 

ALIASES

    None

   

 

REMARKS

    None

 

You may have written a MOF schema by hand and want to test whether it will satisfy the conditions required by DSC. You could use the Test-Dscschema. Suppose we had the following schema:

[ClassVersion("1.0.0.0"), FriendlyName("")]

class Demo_ADUser : OMI_BaseResource

{

       [Key] String UserName;

       [Write, ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure;

};

 

 

Say we save it as buggy.schema.mof.

PS C:\> Test-DscSchema -Schema .\buggy.schema.mof

Test-MockSchema : The Class name Demo_ADUser does not match the Schema name buggy.

At C:\Program

Files\WindowsPowerShell\Modules\DSCPack_ResourceDesigner\DSCPack_ResourceDesigner.psm1:2454 char:21

+             return (Test-MockSchema $Schema $SchemaCimClass)

+                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo         : NotSpecified: (:) [Write-Error], WriteErrorException

    + FullyQualifiedErrorId : ClassNameSchemaNameDifferentError,Test-MockSchema

 

False

 

There you go, it complains that the name of the class and the schema should be the same.

In this post we explored the Resource Designer Tool and saw how easy it is to create our own custom DSC resources. Hope you find it useful!

Given below are the rules which a DSC resource must conform to (this is just for reference and you do not need to worry about them if you use the designer tool):

1)      At least one parameter in the schema is marked as [key]

2)      All parameters MUST be marked with either key, required, write or read property. Additional rules as follows:

a.       [Read] and ([key] or [required] or [write]) can’t coexist.

b.      If multiple qualifiers are specified except [Read], then [key] takes precedence.

c.       If [write] and [required] are specified, then [required] takes precedence.

3)      Class from EmbeddedInstance MUST be either DSC system class or a class defined in the same scope. EmbeddedInstance class should not be DSC resource class i.e. derived from OMI_BaseResource class.

4)      All classes MUST have [ClassVersion] qualifier.

5)      Existence of Get-TargetResource, Set-TargetResource, and Test-TargetResource methods

6)      Set/Test-TargetResource take all [key] and [write] parameters only.

7)      Get-TargetResource takes all [key] parameters and optionally can have [required] as well as [write] parameters

8)      Get/Set/Test-TargetResource do not have any parameters not defined in the schema

9)      Get/Set/Test-TargetResource should have key/required parameter marked as mandatory

 

Updated On 1/13/2014: Removed old version of Resource Designer Tool.  An newer version of this resource can be found here.

 

Abhik Chatterjee

Windows PowerShell Developer

Microsoft

 

20 Nov 15:21

Hungry for more Windows PowerShell Desired State Configuration Resources?

by PowerShell Team

Now that you understand the value and need of Windows PowerShell Desired State Configuration (DSC), and how to declaratively express the intent of machine configuration via the new configuration keyword, you might be wondering how the configuration happens.

Configuration on a machine works because of DSC resources. Windows Server 2012 R2 and Windows Management Framework (WMF) 4.0 come with 12 built-in resources, but that’s not all. Like command extensibility of PowerShell, DSC resources are also extensible–you can create new DSC resources to fill the gap. This blog will walk you through the mechanics of DSC resources, and how to create new custom DSC resources.

The Desired State Configuration (DSC) resource is a PowerShell module that is used to model one or more entities that you want to be in a specific, desired state. In the below example, the DSC resource WindowsFeature is modeled to install or uninstall server roles such as Hyper-V, BranchCache, etc. on the target machine.

image  

Resource naming convention

All the contents of a DSC resource are packaged in to a single directory, so you can deploy DSC resources by using x-copy. By convention, the directory in which the DSC resource is packaged should have the same name as that of the DSC resource. This package contains the following files:

Resource definition file

The resource definition file defines the entity that you want to model. In this definition file, you model the properties of the entity that you want to expose with a CIM class definition. The CIM class should inherit from a base CIM class called OMI_BaseResource. The definition file has the same name as the CIM class, with a .schema.mof extension.

In the below example, a DSC resource named MSFT_RoleResource has a CIM class named MSFT_RoleResource that inherits from OMI_BaseResource CimClass.

class MSFT_RoleResource : OMI_BaseResource

{

};

Friendly name

You can give a DSC resource a more user-friendly name for simplicity and readability by adding the FriendlyName attribute to the CIM class; this name represents the contract of the DSC resource. In the below example, MSFT_RoleResource has the friendly name WindowsFeature.

[ClassVersion("1.0.0"), FriendlyName("WindowsFeature")]

class MSFT_RoleResource : OMI_BaseResource

{

};

 

If a friendly name is specified for a DSC resource, then the same friendly name must be used in the configuration document to reference the DSC resource. Using the resource name to reference it in the configuration document is not supported. However if the friendly name is not specified in the resource definition file, then the resource name can be used in the configuration document.

For more information about how resources are used to author the configuration document, refer to the following previous blog.

Qualifiers

Each property in a CIM class can have one or more of the following qualifiers: Key, Required, Read, and Write. The definition of each qualifier is as follows:

  • The Key property is used to uniquely identify the entity that is modeled by the resource. It is a mandatory property, and it must be defined with only one value; it cannot be an array or a collection.
  • The Required property is not a Key property, but is essential for successful execution of the Get, Set, and Test functionalities of the DSC resource. It is mandatory.
  • The Write properties are used to pass information and values from the configuration to the Get, Set, and Test functionality of the resource, which is essential for its execution.
  • The Read properties cannot be specified  in the configuration;  instead, they are returned as results from the execution of Get functionality.

The following Resource implementation section provides more details about Get, Set, Test functionality.

The following is a sample resource definition file for the resource named MSFT_RoleResource in MSFT_RoleResource.schema.mof file: 

[ClassVersion("1.0.0"), FriendlyName("WindowsFeature")]

class MSFT_RoleResource : OMI_BaseResource

{

      [Key] string Name;

      [Write] string Ensure;

      [Read] string DisplayName;

      [Write,EmbeddedInstance("MSFT_Credential")] string Credential;

}; 

The properties of a resource definition can be a complex object such as MSFT_Credential, as shown in the example above. MSFT_Credential is one of the DSC infrastructure CIM classes; it is used for channeling credentials into DSC resources.

Resource implementation file

The resource Implementation File (.psm1) is a typical Windows PowerShell Module file that implements three methods: Get-TargetResource, Test-TargetResource, and Set-TargetResource. The file has the same name as that of its resource, with a .psm1 extension.

In the example below, the DSC resource MSFT_RoleResource is packaged into a directory called MSFT_RoleResource. The resource definition file is named MSFT_RoleResource.schema.mof, and the resource implementation file is named MSFT_RoleResource.psm1.

 

image 

 

Localized content can be imported in to the resource implementation file (.psm1) by using the conventional PowerShell script internationalization approach. Refer to the following MSDN article for script internationalization.

Every DSC resource must expose the following three commands:

  • Get-TargetResource: Get-TargetResource is used to get the status of the entity modeled by the resource.
  • Test-TargetResource: Test-TargetResource is used to determine whether the entity modeled by resource is in a desired state or not.
  • Set-TargetResource: Set-TargetResource is used to verify that the entity modeled by resource is in a desired state. If the entity modeled by the resource is not in the desired state, then the functionality of Set-TargetResource is responsible for putting the entity in the desired state.

Rules for authoring Get-TargetResource, Set-TargetResource and Test-TargetResource commands 

  • The Get-TargetResource function implements all Key properties defined in the resource schema file. If a DSC resource requires the Required and/or Write properties to successfully fetch the state of the modeled entity, then Required or Write properties can also be in the Get-TargetResource input parameter list, and the values for these properties are propagated to Get-TargetResource during the command execution.
  • Test-TargetResource and Set-TargetResource functions implement all the Key, Required and Write properties defined in the resource schema file.
  • The parameters exposed by Get, Set, and Test must all exist in the schema file, and should not contain any parameter that is not defined in the schema file.
  • All Key and Required parameters must be authored as mandatory parameters in the corresponding Get, Set, and Test functions.

Get-TargetResource

A sample Get-TargetResource implemented in a resource implementation file (.psm1) is as follows:

 

function Get-TargetResource

{

     param

     (     

        [parameter(Mandatory = $true)]

        [ValidateNotNullOrEmpty()]

        [string]

        $Name,

 

        [Parameter(Mandatory=$false)]

        [System.Management.Automation.PSCredential]

        $Credential

     )

 

 

 

        # Add implementation logic to fetch the status of

        # the entity modeled by the resource

 

        # Add all feature properties to the hash table

        $getTargetResourceResult = @{

                                      Name = $feature.Name;

                                      DisplayName = $feature.DisplayName;

                                      Ensure = $ensureResult;

                                    }

 

 

        $getTargetResourceResult;

 

}

The Get-TargetResource returns the status of the modeled entities in a hash table format. This hash table must contain all properties, including the Read properties (along with their values) that are defined in the resource schema. In the example above, the hash table returned by Get-TargetResource contains Name, DisplayName and Ensure properties, along with their values. These properties also exist in the MSFT_RoleResource CimClass definition that was authored in the resource definition file shown above.

Set-TargetResource

A sample Set-TargetResource implemented in a resource implementation file (.psm1) is as follows:

 

function Set-TargetResource

{   

    [CmdletBinding(SupportsShouldProcess=$true)]

    param

    (      

        [parameter(Mandatory=$true)]

        [ValidateNotNullOrEmpty()]

        [string]

        $Name,

 

        [parameter()]

        [ValidateSet("Present", "Absent")]

        [string]

        $Ensure = "Present",

 

        [Parameter(Mandatory=$false)]

        [System.Management.Automation.PSCredential]

        $Credential

    )

 

        # Add implementation logic to make sure that

        # the entity modeled by resource is put a desired state.

 

        Write-Verbose "Executing Set-TargetResource functionality."

 

        for ($i = 1; $i -le 100; $i++ )

        {

            write-progress -activity "Set execution in Progress" -status "$i%    Complete:" -percentcomplete $i;

        }

}

 The Set-TargetResource method should not return any result to the calling code. 

WhatIf mode

As a best practice, Set-TargetResource should support -WhatIf behavior (WhatIf provides a summary of what action would be taken if Set-TargetResource was executed, without actually performing the command). To support -WhatIf behavior, the SupportShouldProcess attribute must be set to True in the cmdlet binding of the Set-TargetResource function, as shown below.

 

function Set-TargetResource

{   

    [CmdletBinding(SupportsShouldProcess=$true)]

    param

    ( 

    )

  }

In the following example, if Set-TargetResource is executed in WhatIf mode, the description of the operation performed is displayed without actually performing the operation. On the other hand, if Set-TargetResource is executed without adding the -WhatIf parameter, the actual operation is run, and the WhatIf description message is not displayed.

 

function Set-TargetResource

{   

    [CmdletBinding(SupportsShouldProcess=$true)]

    param

    (      

        [parameter(Mandatory=$true)]

        [ValidateNotNullOrEmpty()]

        [string]

        $Name,

 

        [parameter()]

        [ValidateSet("Present", "Absent")]

        [string]

        $Ensure = "Present",

 

        [Parameter(Mandatory=$false)]

        [System.Management.Automation.PSCredential]

        $Credential

    )

 

 

        if($PSCmdlet.ShouldProcess("Description about what operation would be performed if Set-TargetResource would be executed."))

        {

            # Add implementation logic to make sure that

            # the entity modeled by resource is put a desired state.

        }

}

 

For more details about SupportShould parameters, refer to the following documentation:

·         http://msdn.microsoft.com/en-us/magazine/cc163293.aspx

·         http://technet.microsoft.com/en-us/magazine/ff677563.aspx

 

Reboot Status

If the machine must be restarted for the logic in Set-TargetResource to take effect, the resource can notify the DSC engine to restart the target, by setting the global variable $global:DSCMachineStatus to 1 before exiting Set-TargetResource method. The example below shows how restart-required status can be set in the Set-TargetResource functionality.

 

function Set-TargetResource

{   

    [CmdletBinding(SupportsShouldProcess=$true)]

    param

    (      

        [parameter(Mandatory=$true)]

        [ValidateNotNullOrEmpty()]

        [string]

        $Name,

 

        [parameter()]

        [ValidateSet("Present", "Absent")]

        [string]

        $Ensure = "Present",

 

        [Parameter(Mandatory=$false)]

        [System.Management.Automation.PSCredential]

        $Credential

    )

 

        # Add implementation logic to make sure

        # that the entity modeled by resource is

        # put a desired state.

 

       

        # If the machine needs to be rebooted

        # for the Set logic to take effect,

        # set the $global:DSCMachineStatus to 1

 

        Write-Warning "A machine reboot would be required."

        $global:DSCMachineStatus = 1;

}

Test-TargetResource

Test-TargetResource should always return a Boolean value of either $true or $false as the result of the test operation. If the entity modeled by the resource is in a desired state, then Test-TargetResource should return $true; if not, it should return $false.

 

A sample Test-TargetResource implemented in a resource implementation file (.psm1) is as follows:

 

function Test-TargetResource

{

    param

    (      

        [parameter(Mandatory = $true)]

        [ValidateNotNullOrEmpty()]

        [string]

        $Name,

 

        [parameter()]

        [ValidateSet("Present", "Absent")]

        [string]

        $Ensure = "Present",

 

        [Parameter()]

        [System.Management.Automation.PSCredential]

        $Credential

    )

 

    # Add implementation logic to validate

    # if the entity modeled by resource is

    # in a desired state or not.

   

    # In this example Test-TargetResource is

    # reporting that the entity modeled by

    # resource is not in the desired state.

    return $false

}

 

Propagating messages from resource

The DSC resource can channel Verbose, Warning, Debug, Error, and Progress messages back to the client side, in appropriate PowerShell message streams. These messages are also collected in the “Microsoft-Windows-DSC/Analytic” channel on the target machine.

 

Deployment of DSC resource

All custom DSC resources should be x-copy deployed to $env:ProgramFiles\WindowsPowerShell\Modules\<Module Name>\DSCResources\<Resource Name>.

Resource consumption

A configuration document is authored to serve as a blueprint of the desired state of the machine. This configuration document contains one or more resources that are modeled to put their corresponding entities in a desired state. For more information about how resources are used to author the configuration document, refer to the previous blog

For more information about DSC, refer to the following TechNet documentation.

I hope I have helped you understand how to create your custom DSC Resource easily, simply by creating a resource definition file, implementing the functionality through Get/Set/Test-TargetResource, and then packaging your resource as a PowerShell module.

 

Sharath Gopalappa

Software Design Engineer

Microsoft

 

Updated on 11/17/2013: Fixed the formatting to be uniform through out.

07 Nov 14:36

Applying Cumulative Updates for System Center Configuration Manager 2012 SP1

by Damian Flynn

With the introduction of System Center 2012, Microsoft has adopted a quarterly based approach to releasing updates for the complete suite of components. Normally these are all released on the same day, which the most recently published (at the time of writing) is Cumulative Update 3 for System Center Configuration Manager (SCCM) 2012 SP1.

The process of deploying these update packs has remained unchanged with each update, making the procedure quite comfortable after the first update cycle you complete. (This would also suggest that the content of this post should remain relevant for any earlier updates, and quite likely for any upcoming updates for the 2012 SP1 product stream.)

If you are relative new to System Center Configuration Manager, and this is indeed your first time facing the update cycle, your initial reaction could easily be forgiven for assuming this to be a complicated process, as the documents available from Microsoft do little to help you get a warm confident feeling. My objective here is to give you back the confidence.

Cumulative Update 3: Preparation

This goes without saying, whether you are having some confidence issues, or you are a tried-and-true expert: Stop now and make a backup of your site database.

Assuming you are following a best practice, this is already happening nighty via a SCCM task that you enabled. If so brilliant! Now go check that backup is actually working. You can check the SCCM log on the primary server (smsbkup.log) and see entries that read "Backup Succeeded for Component."

SCCM: Applying the Update

Most of the confusion is going to be around where you apply the update. For example, if you have an environment similar to mine in which I have a primary server, two management servers, and more than 40 servers acting as deployment points, user state migration roles, etc., then you are likely not looking forward to this job at all.

Now, do you have to install the update on all these servers to which you deployed SCCM roles? And if so, what sequence do you need to approach? Fear not, as the single definite answer is NO, you do not need to update every one of these, you need only update your primary server.

If you have additional hierarchy servers (for example a CAS, additional primary servers, or even a secondary server), then you'll need to apply the update to these top of hierarchy servers. In this case start from the top and work your way down.

Deployment Points and Clients

Now that we have clarified the first of these questions about where do we apply the updates, we still need to address the roles we deployed, right? And your clients?

Sure, we do need to deal with them, but that’s actually the easy part! We are going to use SCCM itself to patch these. And, let's clarify: If you try to take that update you downloaded for Microsoft and use it to patch these other servers, it's not really going to work.

Why? Well that update is an archive of updates and scripts itself, and when you run it on the head of each level in your hierarchy, it will update the associated SQL databases, and – more importantly – it will offer to create in SCCM a set of four packages in your software scope, which will be used to update the rest of your managed environment. It is these four packages that contain the updates for your clients, servers, and we forget, the SCCM console itself.

As you run the installer, it will prompt you to provide a name for the package and its associated program. Eventually you will have provided details for the following new updates:

  • SCCM Management Console
  • SCCM Servers
  • SCCM Clients for X86 Operating Systems
  • SCCM Clients for X64 Operating Systems.

This is what the page looks like in the installer:

Deploy Cumulative Update 3 for SCCM 2012 SP1

Okay, go ahead and run the update on your server. For example, as I have no secondarys or CAS, I am just going to run the update on my primary server (which I backed up), allow the database to be updated, and provide names for the four new updates we just listed, as you would like to see them in your SCCM console (or accept the default names if you prefer). You can click the button on the wizard to show the log so that you can easily monitor what is going on while you enjoy a nice coffee.

 

Great, How do I Update the Clients? How About Servers and Consoles?

Really? You’re a SCCM guru – you don’t need me to tell you how to do this, right? Okay, well just to ensure that I have the right idea, I'll share my understanding with you.

Essentially, the wizard created four new packages for us that we can see these in the Software view of the console. All I have to do is create a deployment for each of these packages, targeted at the respective systems, just as I would do for any other package I would like to distribute. The SCCM will do the rest.

And that is all there is to it! Not as scary as we first expected, right? Good luck with the updates!

07 Nov 14:29

LastPass 3.0 Is Here: New Design, New Features!

by Amber Gott

Excited doesn’t begin to express how we feel about introducing LastPass 3.0. Our new release features an updated, clean design across the LastPass browser addons, the iOS and Android mobile apps, and our website itself. We’ve worked hard to make LastPass easier to use and less intrusive.

Highlights from LastPass 3.0 include:

  • Revamped user experience and user interface
  • Field icon menus for easy access to logins and LastPass tools
  • A Shared Family Folder for up to 5 users
  • Expanded Shared Folder features for LastPass Enterprise
  • A revamped LastPass for Applications
  • Secure Note history, to track changes to your notes
  • Windows 8.1 support
  • and more

New Design, New Experience


In LastPass 3.0, we’ve changed the way LastPass notifies and interacts with you. LastPass focuses more on the website's fields, so there are less steps to get what you need. We're also phasing out the notification bars at the top of the browser.


A clickable icon now appears on the website's fields. The LastPass field icon is dynamic, showing you options that match what you would want to do with that field. If it’s a login form, you’ll see your matching logins for that site.


If you don’t have any logins stored for that site, LastPass will ask if you want to save it:


If it’s a “create password” field, you’ll see the Password Generator:


If it’s a shopping form, you’ll see your Profiles:


The field icon menu expands so you can quickly access all the main LastPass features:


The LastPass browser addon menu has been simplified, and we've added immediate access to search, so you can quickly find the sites and notes you need:


The vault has also been updated to reflect the new look and feel:


Improved Mobile Experience


The Premium mobile apps for Android and iOS now have a "browser-forward experience", meaning the browser is integrated with the vault for easy site searching and launching. The vault on both platforms is easily searchable, where you can add, edit, and update your passwords at a moment’s notice.


The LastPass browser now has quicker access to your logins and Profiles. You can add sites easily, generate new passwords quickly, and enjoy a more seamless mobile experience overall.

 

LastPass Shared Family Folder

 

We've streamlined sharing for our users. LastPass Premium users can now use a Shared Family Folder with up to 5 family members to manage and access joint accounts. Each LastPass user can be added to the Shared Family Folder, and the logins or notes can then be dragged-and-dropped into the Shared Folder.


Updates are then kept in sync across all users sharing the folder. See our full article in the user manual for how to get started; only the user creating the folder needs to have LastPass Premium.

Updates for LastPass Enterprise


LastPass Enterprise administrators can now give Shared Folder access to non-Enterprise LastPass users. Up to 3, non-Enterprise users can be given access to any Enterprise Shared Folder. The new functionality is particularly useful for those who may need to give contractors or part-time employees temporary access to sites. LastPass for Applications has also received a number of improvements.

We're Thrilled to Reach Another Milestone!


We are so thrilled to share LastPass 3.0 with our community. We hope you enjoy the clean design and less intrusive experience. As always, we owe a big “thank you” to our community for your continued support. We're committed to the ongoing improvement of our service, and strive to  provide a great experience for our users. Let us know what you think in the comments below!

Thanks,
The LastPass Team

FAQs


How do I disable the "ticker" in the icon?
From the LastPass Icon > Preferences >  Notifications, uncheck the "Show Matching Sites Count in Toolbar" option.

How do I move my matching sites list back to the main icon menu?
In the LastPass Icon > Preferences > Advanced, select the Show matching sites in top level menu" option.

Can I go back to the old notification bars?
First, be sure that you're clicking the icons that now appear in your username and password fields to try to enter your data. If you've tested it and you don't like clicking the field icons, you can enable the old notification bars in the LastPass Icon >  Preferences > Notifications, and disable the field icons from there. We'd appreciate specific feedback so we can keep fine-tuning our new release.
06 Nov 23:13

PowerTip: Find if Computer has .NET Framework 4.5

by The Scripting Guys

Summary: Use Windows PowerShell to find if a computer has .NET Framework 4.5.

Hey, Scripting Guy! Question How can I use Windows PowerShell to find if my machine has .NET Framework 4.5 (required for Windows PowerShell 4.0)?

Hey, Scripting Guy! Answer Here's a little function that finds this information for you:

function Test-Net45

{

    if (Test-Path 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full')

    {

if (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full' -Name Release -ErrorAction SilentlyContinue)

{

    return $True

}

return $False

    }

}

You can run it remotely, too:

PS C:\ps-test> Invoke-Command -ComputerName Server01 -ScriptBlock {

function Test-Net45

{

>> if (Test-Path 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full')

>> {

>> if (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full' -Name Release -ErrorAction SilentlyContinue)

>> {

>>     return $True

>> }

>> return $False

>> }

>> }
>> #Run it now

>> Test-Net45}

True

06 Nov 14:33

Download SysInternals with PowerShell

by Jeffery Hicks

sysinternals Like many IT Pros, I’m a big fan of the utilities that make up the Sysinternals suite. A number of years ago, Microsoft created a “live” web directory (http:\\live.sysinternals.com\tools) that allowed you direct access to each utility. While this is very handy, personally I prefer to keep a local version. I used to periodically check the site and update my local folder, but now I can use PowerShell.

#requires -version 3.0

<#
Download Sysinternals tools from web to a local folder.

  ****************************************************************
  * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED *
  * THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK.  IF   *
  * YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, *
  * DO NOT USE IT OUTSIDE OF A SECURE, TEST SETTING.             *
  ****************************************************************
#>

[cmdletbinding(SupportsShouldProcess)]

Param(
[Parameter(Position=0)]
[ValidateScript({Test-Path -Path $_})]
[string]$Destination = "G:\SysInternals"
)

#start the WebClient service if it is not running
if ((Get-Service WebClient).Status -eq 'Stopped') {
     Write-Verbose "Starting WebClient"
     #always start the webclient service even if using -Whatif
     Start-Service WebClient -WhatIf:$false
     $Stopped = $True
}
else {
    <#
     Define a variable to indicate service was already running
     so that we don't stop it. Making an assumption that the
     service is already running for a reason.
    #>
    $Stopped = $False
}

#get current files in destination
$current = dir -Path $Destination -File

Write-Host "Updating Sysinternals tools from \\live.sysinternals.com\tools to $destination" -ForegroundColor Cyan

foreach ($file in $current) {
  #construct a path to the live web version and compare dates
  $online = Join-Path -path \\live.sysinternals.com\tools -ChildPath $file.name
  Write-Verbose "Testing $online"
  if ((Get-Item -Path $online).LastWriteTime.Date -ge $file.LastWriteTime.Date) {
    Copy-Item $online -Destination $Destination -PassThru
  }
}

Write-Host "Testing for online files not in $destination" -ForegroundColor Green

#test for files online but not in the destination and copy them
dir -path \\live.sysinternals.com\tools -file | 
Where {$current.name -notcontains $_.name} |
Copy-Item -Destination $Destination -PassThru

<#
alternative but this might still copy files that haven't
really changed
Robocopy \\live.sysinternals.com\tools $destination /MIR
#>

if ( $Stopped ) {
    Write-Verbose "Stopping web client"
    #always stop the service even if using -Whatif
    Stop-Service WebClient -WhatIf:$False
}

Write-Host "Sysinternals Update Complete" -ForegroundColor Cyan
#end of script

My version requires PowerShell 3.0. You need to have the WebClient service running in order to list the Internet files. My script has code to start and stop the service as needed. Although if it detects the service is already running, the script won’t stop it under the assumption that you probably had it running for a reason.

The logic behind the script is pretty simple, if the date of the online version is greater than the local version, copy the file. One thing I ran into though is that there can be a discrepancy with the time stamps due to time zones and/or daylight savings time. I couldn’t find an easy way to take those things into account so I opted to simply test the date and ignore the time.

The next thing I should do is set up a PowerShell scheduled job to run the script on a monthly basis. I hope you’ll let me know how this works out for you.

06 Nov 14:32

IE11 makes browsing for the Blind & Visually Impaired, easier

by AnandK@TWC
ie10-metro-logo

Windows 8 includes several accessibility features that make working with the computer a lot easier for the challenged. Starting with Windows 8, Internet Explorer 11 has made things even easier for the Blind and Visually Impaired. Those of you who [...]

This post IE11 makes browsing for the Blind & Visually Impaired, easier is from TheWindowsClub.com.

05 Nov 20:53

Building a Demo Active Directory: Part 2

by The Scripting Guys

Summary: Build Windows PowerShell variables to design an organizational unit structure.

Hey, Scripting Guy! Question Hey, Scripting Guy!

Can Windows PowerShell provide a consistent way to build a demo structure in Active Directory that includes organizational units and security groups?

—RL

Hey, Scripting Guy! Answer Hello RL,

Honorary Scripting Guy, Sean Kearney here, filling in for our good friend, Ed.

Welcome to Part 2 of this series. To catch up, read Building a Demo Active Directory: Part 1.

We absolutely can use Windows PowerShell in this way. A good friend of mine, Rick Claus from Microsoft, asked me this very same question. “Hey, Sean,” our good friend piped up after removing his Tilley. “I have to build demo environments all the time, and I would like an easier way to build the structure. I don’t suppose you know of a way to do this in Windows PowerShell, do you?”

Of course, the minute he said, “PowerShell,” the answer was, “Yes, of course, O Green Hatted one, you can!”

So our first challenge is to decide what our structure will look like. As a demo environment, we probably need a decent and simple structure…maybe a main unit, some offices, and a division in each office.

Contoso.local

            Offices

                        Seattle

                                    Accounting

                                    HR

                                    IT

                                    Exec

                        Ottawa

                                    Accounting

                                    HR

                                    IT

                                    Exec

                        New Orleans

                                    Accounting

                                    HR

                                    IT

                                    Exec

Then within each division, we might want a security group. For our demo environment, we can build a simple set of names, such as:

NewOrleans-Accounting

Ottawa-IT

Seattle--HR

First we’re going to name our Base OU. In this example, we’re simply going to call it “Offices”, but you can choose any name you like. I’d recommend something that actually makes sense. Calling your Base OU “FlyingWombats” might not make very much sense. But to each, his or her own…

$BaseOU=”Offices”

Now we’re going to name six cities that will sit as children under this OU:

$CityOU=”Tokyo”,”Redmond”,”Ottawa”,”Madrid”,”New Orleans”,”Queensland”

Now we’ll define the four divisions. Of course, it could be more, but we’re going to keep this quiet simple:

$DivisionOU="Sales","Marketing","HR","Finance"

So if you’re thinking out loud, I’ll bet you’re guessing, “Oh, this looks like an easy answer!” Well, really it is!

So today we’ll be using the cmdlet in Active Directory called New-ADOrganizationalUnit. This will allow us to populate the OU’s in our Active Directory demo environment.

To work with these cmdlets properly, we need to supply the distinguished name for the path in many cases. So first let’s define that. Our main root, of course, will be our domain name:

$Domain=”DC=Contoso,DC=local”

Now we’ll define the path for our company OU where all the offices will exist:

$CompanyPath="OU=$BaseOU,"+$Domain

Now that all the prep work is set up, what shall we do? Let’s build a simple loop structure to build it up! First create the base organizational unit:

NEW-ADOrganizationalUnit -name $BaseOU -path $Domain

Next we’ll step through our list of cities and create some OU’s based on them. Let’s also remember that we’ll be targeting the main CompanyPath as our starting point:

# Gather through list of Cities

Foreach ($City in $CityOU)

 {

 # Create OU for City

 NEW-ADOrganizationalUnit -path $CompanyPath -name $City

So far, so good? Next we’ll step through our list of divisions and populate them. We need to adjust the path to incorporate each city as part of the path for the division:

 # Gather through list of Divisions

 Foreach($Division in $DivisionOU)

 

 {

            # Create Division within City

            NEW-ADOrganizationalUnit -path "OU=$City,$CompanyPath" -name $Division

 }

}

With this loop completed, we now have a rudimentary structure that we can populate. But did I mention security groups? Why yes, I did. And that’s for another story tomorrow.

I invite you to follow the Scripting Guys on Twitter and Facebook. If you have any questions, send email to scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Sean Kearney, Honorary Scripting Guy and Windows PowerShell MVP 

05 Nov 20:44

Building a Demo Active Directory: Part 1

by The Scripting Guys

Summary: Leverage Windows PowerShell in Windows Server 2012 to create a new Active Directory forest.

Hey, Scripting Guy! Question Hey, Scripting Guy!

I often have to put together demo environments, and I need a new empty Active Directory forest. Is there any way I can do this faster than by using the GUI…maybe with Windows PowerShell?

—TM

Hey, Scripting Guy! Answer Hello TM,

Honorary Scripting Guy, Sean Kearney here, filling in for our good friend, Ed.

I’ve also had to build demo environments—sometimes as a proof of concept for a client, and sometimes as an environment when I’m doing presentations.

In the old days, the way I had to do it was either by using the GUI or learn the DCPromo command. But in Windows Server 2012, life got so much better. The GUI and Windows PowerShell produce a far better team.

So here we have a blank server. The only thing that has been done is that the static IP address has been configured, and it has been named CONTOSO-DC.

Promoting this to a domain controller by using Windows PowerShell is actually pretty easy. I can do this with the GUI of course, but that would be about five or six pretty pictures, which I can replace with a few lines in Windows PowerShell.

Our first process is to enable the Active Directory Domain Services on the server. In Windows PowerShell, we can just execute this command:

Install-WindowsFeature AD-Domain-Services –IncludeManagementTools –IncludeAllSubFeature

Now I need to show you a really cool feature that was introduced in Windows Server 2012—which is why I love using it more than previous versions. Let’s run through the wizard and turn this into a full domain controller in a new domain called…well…CONTOSO.LOCAL.

After the domain services are added, you’ll see a yellow triangle with an exclamation point near the top of the new Server Manager. Click that, and you’ll see a Post Deployment Configuration option. Click Promote this server to a domain controller.

Image of menu

We’ll expand this task and select the hyperlink under Action.

Image of menu

From this point, we should see some familiar screens. We’re going to add the new forest called CONTOSO.LOCAL.

Image of menu

We’re also going to go cutting edge and choose our forest and domain functional level at Windows Server 2012. We’ve also populated our Directory Services Restore Mode password. And now the most insecure thing ever! Here’s the password: Secret321!

There is no previous domain, so of course we’ll be skipping by that screen. We’ll verify the NETBIOS name for our domain as shown in the following screen.

Image of menu

And verify our paths. (OK! You in the back! Stop yawning.)

Image of menu

And now the coolest screen of all in Windows Server 2012—the Review Options screen:

Image of menu

The reason for its coolness is the View Script button in the lower-right. Clicking it shows us the Windows PowerShell script that is about to run.

Image of command output

What we’re going to do now is cancel the wizard and paste this into our Windows PowerShell Console to see what it does. I’m looking, and I don’t see my password anywhere.

Image of command output

Aha! It’s prompting for the password. But I’ll bet there is a parameter we can supply the password to. Because the prompt is SafeModeAdministratorPassword, that would usually be the missing parameter.

I’m going to guess that we have to convert this password to a secure string because most commands from Microsoft won’t accept a clear text password directly. So we’ll drop the following command inside our parameter called -SafeModeAdministratorPassword:

(CONVERTTO-SecureString “Secret321!” –asplaintext –force)

So the really cool part with this prebuilt script is that we can easily modify it to have our variables at the top of the script to simply substitute into the command. With it designed in this way, a person with no administrative knowledge could actually spin up their own domain controller in a lab by only to knowing three key details:

  • New domain name
  • New NetBIOS name
  • Default password for Administrator

$Domainname=”Contoso.local”

$DomainNetbios=”Contoso”

$Password=”Secret321!”

Now there is, of course, one additional piece to remember. When we promote to a domain controller in a new domain, it will grab the local Administrator password and set that as the default. To ensure our new domain accepts the password defined by the user in our script, we’ll need to reset the local Administrator password.

Now I could use the [ADSI] accelerator for this, but I love the fact I can use legacy solutions to this day in Windows PowerShell:

NET USER Administrator $Password

Now with all of this in place, we can have a nice little script to spin up a new test domain:

Param(

[string]$DomainName=’Contoso.local’,

[string]$DomainNETBIOSName=’CONTOSO’,

[string]$Password=’Secret321!’

)

Import-module ADDSDeployment

 

# Add Domain Services to Server

INSTALL-WindowsFeature AD-Domain-Services –IncludeManagementTools -IncludeAllSubFeature

 

# Reset local Administrator password to

# One defined in Script

NET USER Administrator $Password

 

# Install our Shiny new Forest. It’s a good place for SQuirreLs to see *’s

#

Install-ADDSForest –SkipPreChecks –CreateDnsDelegation:$False `

–DatabasePath ‘C:\Windows\NTDS’ –DomainMode ‘Win2012’ `

–DomainName $DomainName –DomainNetbiosname $DomainNETBIOSName `

–ForestMode ‘Win2012’ –InstallDns:$True –Logpath ‘C:\Windows\NTDS’ `

–NoRebootOnCompletion:$True –SysvolPath ‘C:\Windows\SYSVOL’ `

–SafeModeAdministratorPassword (CONVERTTO-SecureString $Password –asplaintext –force) `

–force

 

# Restart and Get ‘er done

RESTART-COMPUTER –force

Tomorrow we’ll expand on this domain controller, and we’ll work on prepopulating that environment without us doing all the typing!

I invite you to follow the Scripting Guys on Twitter and Facebook. If you have any questions, send email to scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Sean Kearney, Honorary Scripting Guy and Windows PowerShell MVP

31 Oct 14:40

Windows Management Framework (PowerShell) 4.0 is now available – ensure you already have .NET 4.5

by Jonathan Medd

Update 30/10/2013: There’s an updated post on the PowerShell Team Blog which now describes this situation with .NET 4.5 as a pre-requisite in more detail.

———————————————————————————————–

PowerShell 4.0 which shipped as part of Windows Server 2012 R2 and Windows 8.1 is now available for down-level Windows versions via the downloadable Windows Management Framework 4.0.

WMF 4.0 contains updated versions of the following features:

Windows PowerShell
Windows PowerShell Integrated Scripting Environment (ISE)
Windows PowerShell Web Services (Management OData IIS Extension)
Windows Remote Management (WinRM)
Windows Management Infrastructure (WMI)

Additionally, we have added a new and exciting Windows PowerShell feature which is available in WMF 4.0: Windows PowerShell Desired State Configuration (DSC)

To use this updated management infrastructure to manage Windows 7 SP1, Windows Embedded 7, Windows Server 2008 R2 SP1, and Windows Server 2012, WMF 4.0 must be installed on computers that are running the previously-released operating systems.

For this Release, WMF 4.0 installs only on the following operating systems:

Operating System Service Pack Level Editions
Windows 7 Service Pack 1 All
Windows Server 2008 R2 Service Pack 1 All except IA64
Windows Server 2012   All except IA64
Windows Embedded 7   All

Note that Windows 8 is not listed and you are required to take the free upgrade to Windows 8.1 to get PowerShell 4.0.

One important requirement that is worth taking particular notice of is that .NET Framework 4.5 is a pre-requisite. While you may have installed this on your Windows 7 machine, it maybe not that likely that you have installed it on your server installations.

While this information is in the release notes, there is nothing in the installation that warns you of this requirement and an installation attempt without it results in (IMHO) a slightly  bizarre outcome.

In this example I installed WMF 4.0 on a Windows Server 2008 R2 system with the WMF 2.0 / PowerShell 2.0 combination that ships as part of the OS.

The OS currently contains .NET Framework 3.5.

WMF4_01

Tip: You can quickly find your latest .NET version with the following one-liner

<br /><br />&amp;nbsp;<br /><br />Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -Recurse | Get-ItemProperty -name Version -EA 0 | Where-Object { $_.PSChildName -match '^(?!S)\p{L}'} | Sort-Object version -Descending | Select-Object -ExpandProperty Version -First 1<br /><br />

Having downloaded the correct WMF 4.0 version for Windows Server 2008 R2 I’ve started the installation:

WMF4_02

WMF4_03

WMF4_04

Once the installation is complete, I check the version of PowerShell and discover that it is still 2.0.

<br /><br />$psversiontable<br /><br />

WMF4_05

So nothing much seems to have changed! If you look carefully in the release notes though, installing without .NET Framework 4.5, results in two QFE hotfixes being installed.

Note: When you run the WMF 4.0 installation package, the following updates are installed first:

Examining these hotfixes we can see two hotfixes have been installed:

WMF4_06

(Confusingly, one of these KB2809215, is actually the KB2823180 mentioned in the release notes.)

If we attempt to install WMF 4.0 again we are told that it already has been installed:

WMF4_07

So, let’s see what happens if we install the .NET Framework 4.5 pre-requisite:

WMF4_08

WMF4_09

Test the install:

WMF4_10

Now try the install again

WMF4_11

WMF4_12

WMF4_13

After reboot, we can confirm we now have PowerShell 4.0.

WMF4_14

Got a headache yet? The crux of the story is make sure you have .NET Framework 4.5 before installing WMF 4.0 :-)

30 Oct 22:14

Windows Management Framework (PowerShell) 4.0 is now available – ensure you already have .NET 4.5

by Jonathan Medd

Update 30/10/2013: There’s an updated post on the PowerShell Team Blog which now describes this situation with .NET 4.5 as a pre-requisite in more detail.

———————————————————————————————–

PowerShell 4.0 which shipped as part of Windows Server 2012 R2 and Windows 8.1 is now available for down-level Windows versions via the downloadable Windows Management Framework 4.0.

WMF 4.0 contains updated versions of the following features:

Windows PowerShell
Windows PowerShell Integrated Scripting Environment (ISE)
Windows PowerShell Web Services (Management OData IIS Extension)
Windows Remote Management (WinRM)
Windows Management Infrastructure (WMI)

Additionally, we have added a new and exciting Windows PowerShell feature which is available in WMF 4.0: Windows PowerShell Desired State Configuration (DSC)

To use this updated management infrastructure to manage Windows 7 SP1, Windows Embedded 7, Windows Server 2008 R2 SP1, and Windows Server 2012, WMF 4.0 must be installed on computers that are running the previously-released operating systems.

For this Release, WMF 4.0 installs only on the following operating systems:

Operating System Service Pack Level Editions
Windows 7 Service Pack 1 All
Windows Server 2008 R2 Service Pack 1 All except IA64
Windows Server 2012   All except IA64
Windows Embedded 7   All

Note that Windows 8 is not listed and you are required to take the free upgrade to Windows 8.1 to get PowerShell 4.0.

One important requirement that is worth taking particular notice of is that .NET Framework 4.5 is a pre-requisite. While you may have installed this on your Windows 7 machine, it maybe not that likely that you have installed it on your server installations.

While this information is in the release notes, there is nothing in the installation that warns you of this requirement and an installation attempt without it results in (IMHO) a slightly  bizarre outcome.

In this example I installed WMF 4.0 on a Windows Server 2008 R2 system with the WMF 2.0 / PowerShell 2.0 combination that ships as part of the OS.

The OS currently contains .NET Framework 3.5.

WMF4_01

Tip: You can quickly find your latest .NET version with the following one-liner

<br /><br />&amp;nbsp;<br /><br />Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -Recurse | Get-ItemProperty -name Version -EA 0 | Where-Object { $_.PSChildName -match '^(?!S)\p{L}'} | Sort-Object version -Descending | Select-Object -ExpandProperty Version -First 1<br /><br />

Having downloaded the correct WMF 4.0 version for Windows Server 2008 R2 I’ve started the installation:

WMF4_02

WMF4_03

WMF4_04

Once the installation is complete, I check the version of PowerShell and discover that it is still 2.0.

<br /><br />$psversiontable<br /><br />

WMF4_05

So nothing much seems to have changed! If you look carefully in the release notes though, installing without .NET Framework 4.5, results in two QFE hotfixes being installed.

Note: When you run the WMF 4.0 installation package, the following updates are installed first:

Examining these hotfixes we can see two hotfixes have been installed:

WMF4_06

(Confusingly, one of these KB2809215, is actually the KB2823180 mentioned in the release notes.)

If we attempt to install WMF 4.0 again we are told that it already has been installed:

WMF4_07

So, let’s see what happens if we install the .NET Framework 4.5 pre-requisite:

WMF4_08

WMF4_09

Test the install:

WMF4_10

Now try the install again

WMF4_11

WMF4_12

WMF4_13

After reboot, we can confirm we now have PowerShell 4.0.

WMF4_14

Got a headache yet? The crux of the story is make sure you have .NET Framework 4.5 before installing WMF 4.0 :-)

29 Oct 15:18

Opening the Virtual Machine Remote Console through PowerCLI

by Alan Renouf

With the 5.5 R1 release PowerCLI got even better. With the introduction of the new Open-VMConsoleWindow cmdlet you can access the virtual machine console of both vCenter Server and vCloud Director virtual machines. To open a virtual machine console window, simply pass a powered-on virtual machine to the Open-VMConsoleWindow cmdlet:

Get-VM “Win2k3” | Open-VMConsoleWindow

As a result, the cmdlet opens a Web page containing the virtual machine remote console:

clip_image002

You can even open the console in full screen mode – either by specifying the corresponding cmdlet parameter or by clicking the Full Screenbutton on the Web page:

Open-VMConsoleWindow –VM “Win2k3” –FullScreen

Unless configured otherwise, the cmdlet opens the virtual machine console in the default Web browser on your machine. If you want to use a different browser, you can do so by specifying it in the PowerCLI configuration. You will need to specify the full path to the browser’s executable file:

Set-PowerCLIConfiguration –VMConsoleWindowBrowser “C:\Program Files (x86)\Mozilla Firefox\firefox.exe”

To switch back to using the default browser, simply specify “$null” for the “VMConsoleWindowBrowser” setting.

How does this work under the covers?

In order to display the virtual machine console, PowerCLI uses the VMRCbrowser plug-in embedded in a Web page. This plug-in is installed during the installation of PowerCLI. It supports 32-bit Internet Explorer, Mozilla Firefox, and Google Chrome browsers. The Web page is located at “<PowerCLI install dir>/VMConsoleWindow/” – have a look at it if you want to get the full details or make modifications.

Opening the virtual machine console requires authentication in the form of a token. For vSphere virtual machines this token is acquired through the “AcquireCloneTicket()” method of the SessionManager API object, and for vCloud Director – through the “AcquireTicket()” method of the VirtualMachine API object. In both cases the token is valid for 30 secondsfor single use. The token, virtual machine ID, and the host it’s running on (along with other parameters) are passed as URL parameters to the above-mentioned Web page. If you want to get hold of just this URL (for example, if you want to run Firefox with a specific profile) – you can do so by specifying the “UrlOnly” parameter:

$url = Open-VMConsoleWindow –VM “Win2k3” –UrlOnly

.”C:\Program Files (x86)\Mozilla Firefox\firefox.exe” -P Work $url

With this new cmdlet you now have one less reason to use the vSphere Web Client and can switch entirely to PowerCLI as a single tool for managing your entire virtual infrastructure! How cool is that!

Getting more from the Open-VMConsoleWindow

Another way in which this cmdlet can be used is to solve a common use case in virtual environments.  Often VM owners will want access to their console to troubleshoot an OS or to have the ability to enter the BIOS, this often leads to vSphere Administrators giving people access to the vSphere Web Client or vSphere Client.

As we know there are more actions than opening a console in the full clients and therefore these VM owners often get new ideas about features they would like to use but do not have permissions to do so.  With this cmdlet and other free tools we can easily give the users access to a console window to open their VM without them knowing about the full vSphere Clients.

An example of this is in the below video where we create a scripted application which we can send to our users in just 5 lines of code! Check it out…

clip_image002[8]This post was created by Dimitar Barfonchovski.Dimitar joined VMware and the PowerCLI team in 2007. He is member of the development part of the team and his main responsibilities are the functional design and implementation of features for the vSphere and vCloud PowerCLI components.

As with all members of the team, he is working to deliver a good and valuable product. He is also working to improve all processes and tools involved in the product development and validation.