Quantcast
Channel: Hey, Scripting Guy! Blog
Viewing all 3333 articles
Browse latest View live

PowerTip: Customize How PowerShell Displays a Date

$
0
0

Summary: Easily customize the way Windows PowerShell displays a date.

Hey, Scripting Guy! Question How can I use Windows PowerShell to easily display the date as day-dash-month-dash-four-digit year?

Hey, Scripting Guy! Answer Use the Get-Date cmdlet,specify a custom format by using the Format parameter, and use dd for the date, M for the month and yyyy for a four-digit year (this is case sensitive):

Get-Date -Format "dd-M-yyyy"


PowerShell Workflow for Mere Mortals: Part 3

$
0
0

Summary: Microsoft Scripting Guy Ed Wilson continues his five-part series about Windows PowerShell Workflow.

Hey, Scripting Guy! Question Hey, Scripting Guy! So what’s up with Windows PowerShell workflows and activities? I do not know what an activity is. Can you help me?

—CJ

Hey, Scripting Guy! Answer Hello CJ,

Microsoft Scripting Guy, Ed Wilson, is here. Ah…this afternoon, I am sipping a cup of Darjeeling Earl Grey tea with a bit of cinnamon stick, and I added just a bit of lavender honey from a nearby lavender farm. I am accompanying my tea with a 90% cocoa bar with black currants and hazelnuts. The combination is absolutely stunning.

Note This is the third in a five-part series of blog posts about Windows PowerShell Workflow for “mere mortals.” Before you read this post, please read: 

For more information about workflow, see these Hey, Scripting Guy! Blog posts: Windows PowerShell Workflow

Workflow activities

A Windows PowerShell Workflow is made up of a series of activities. In fact, the basic unit of work in a Windows PowerShell Workflow is called an activity. There are five types of Windows PowerShell Workflow activities that are available for use. The following table describes the types of activities.

Activity

Description

CheckPoint-Workflow (alias = PSPersist)

Takes a checkpoint. Saves the state and data of a workflow in progress. If the workflow is interrupted or rerun, it can restart from any checkpoint.

Use the Checkpoint-Workflow activity along with the PSPersist workflow common parameter and the PSPersistPreference variable to make your workflow robust and recoverable.

 

ForEach -Parallel

Runs the statements in the script block once for each item in a collection. The items are processed in parallel. The statements in the script block run sequentially.

Parallel

Allows all statements in the script block to run at the same time. The order of execution is undefined.

Sequence

Creates a block of sequential statements within a parallel script block. The Sequence script block runs in parallel with other activities in the Parallel script block. However, the statements in the Sequence script block run in the order in which they appear. Sequence is valid only within a Parallel script block.

Suspend-Workflow

Stops a workflow temporarily. To resume the workflow, use the Resume-Job cmdlet.

 Windows PowerShell cmdlets as activities

Windows PowerShell cmdlets from the core modules are automatically implemented as activities for use in a Windows PowerShell Workflow. These core modules, all begin with the name Microsoft.PowerShell. To find these cmdlets, I can use the Get-Command cmdlet as shown here:

Get-Command -Module microsoft.powershell*

The command and the associated output from the command are shown in the image that follows.

Image of command output

Disallowed core cmdlets

However, not all of the cmdlets from the Windows PowerShell core modules are permitted as automatic activities for Windows PowerShell Workflows. The reason for this is that some of the core cmdlets do not work well in workflows. A quick look at the disallowed list makes this abundantly clear. The following table lists the disallowed core cmdlets.

 

Add-History

Invoke-History

Add-PSSnapin

New-Alias

Clear-History

New-Variable

Clear-Variable

Out-GridView

Complete-Transaction

Remove-PSBreakpoint

Debug-Process

Remove-PSSnapin

Disable-PSBreakpoint

Remove-Variable

Enable-PSBreakpoint

Set-Alias

Enter-PSSession

Set-PSBreakpoint

Exit-PSSession

Set-PSDebug

Export-Alias

Set-StrictMode

Export-Console

Set-TraceMode

Get-Alias

Set-Variable

Get-History

Start-Transaction

Get-PSBreakpoint

Start-Transcript

Get-PSCallStack

Stop-Transcript

Get-PSSnapin

Trace-Command

Get-Transaction

Undo-Transaction

Get-Variable

Use-Transaction

Import-Alias

Write-Host 

Non-Automatic cmdlet activities

If a cmdlet is not in the Windows PowerShell core modules, it does not mean that it is excluded. In fact, it probably is not excluded. Therefore, when a non-core Windows PowerShell cmdlet is used in a Windows PowerShell Workflow, Windows PowerShell will automatically run the cmdlet as an InlineScript activity.

An InlineScript activity permits me to run commands in a Windows PowerShell workflow, and to share data that would not be otherwise permitted.

In the InlineScript script block, I can call all Windows PowerShell commands and expressions and share state and data within the session. This includes imported modules and variable values. For example, the cmdlets listed in the previous table that are not permitted in a Windows PowerShell workflow, could be included in an InlineScript activity.

Parallel activities

To create a Windows PowerShell Workflow that uses a parallel workflow activity, I use the Parallel keyword, and I supply a script block. The following workflow illustrates this technique:

WorkFlow Get-EventLogData

{

 Parallel

 {

   Get-EventLog -LogName application -Newest 1

   Get-EventLog -LogName system -Newest 1

   Get-EventLog -LogName 'Windows PowerShell' -Newest 1 } }

When I run the script that contains the Get-EventLogData workflow, I go to the execution pane of the Windows PowerShell ISE to execute the workflow. What happens is that the three Get-EventLog cmdlet commands execute in parallel. This results in a powerful and quick way to grab event log data. If I call the workflow with no parameters, it runs on my local computer. This is shown here:

Image of command output

The cool thing is that with a Windows PowerShell Workflow, I automatically gain access to several automatic parameters. One of the automatic parameters is PSComputerName. Therefore, with no additional work (this workflow does not exist on Server 1 or Server2—it only exists on my workstation), I can use the automatic PSComputerName workflow parameter, and run the workflow on two remote servers. This is shown here:

Image of command output

Because I am not accessing the PSComputerName automatic parameter directly within my Windows PowerShell activity, I am actually using an automatic workflow parameter. For more information, see the following online Help: about_WorkflowCommonParameters.

There are also workflow activity-specific common parameters. For more information, see Using Activities in Script Workflows.

CJ, that is all there is to using Windows PowerShell Workflow activities. Windows PowerShell Workflow Week will continue tomorrow when I will talk about more Windows PowerShell Workflow activities.

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 

PowerTip: Use PowerShell to Display Date, Time, and Hour

$
0
0

Summary: Use Windows PowerShell to display date, time, and hour in 24-hour format.

Hey, Scripting Guy! Question How can I use Windows PowerShell to get the hour of the day in 24-hour format?

Hey, Scripting Guy! Answer Use the Get-Date cmdlet and specify the “%H” pattern to the UFormat parameter (H is case sensitive):

get-date -UFormat "%H"

PowerShell Workflow for Mere Mortals: Part 4

$
0
0

Summary: Microsoft Scripting Guy, Ed Wilson, continues his five-part series about Windows PowerShell Workflow.

Hey, Scripting Guy! Question Hey, Scripting Guy! Yesterday you talked about Windows PowerShell Workflow activities. But you only demonstrated the Parallel activity. Is there something you can share with me about some of the other types of activities? In particular I am interested in checkpoints because I think they can help me.

—AP

Hey, Scripting Guy! Answer Hello AP,

Microsoft Scripting Guy, Ed Wilson, is here. This morning, it is really foggy outside. To be honest, it seems to look more like fall than the end of summer. But then, I am not a real weather person—I don’t even play one on TV. It is fairly humid and fairly cool—a nice morning for a cup of English Breakfast tea. I am not in the mood to experiment today, and so I am going with a standard recipe of mine: Three scoops of English Breakfast tea, a scoop of lemon grass, and a single crushed cinnamon stick. I let it steep for three minutes and 45 seconds, grab my tea pot, my Surface RT, and head outside to check email.

AP, you want to talk about checkpoints in a Windows PowerShell workflow today. No problem…

Note  This is the fourth in a five-part series of blog posts about Windows PowerShell Workflow for “mere mortals.” Before you read this post, please read: 

For more information about workflow, see these Hey, Scripting Guy! Blog posts: Windows PowerShell Workflow

Checkpoints Windows PowerShell workflow

If I have a Windows PowerShell Workflow, and I need to save the workflow state or data to a disk while the workflow runs, I can configure a checkpoint. In this way, if something interrupts the workflow, it does not need to restart completely. Instead, the workflow resumes from the point of the last checkpoint. Setting a checkpoint in a Windows PowerShell Workflow is sometimes referred to as “persistence” or “persisting a workflow.” Because Windows PowerShell Workflows run on large distributed networks, or they control the execution of long running tasks, it is vital that the workflow can handle interruptions.

Understanding checkpoints

A checkpoint is a snapshot of the workflow’s current state. This includes the current values of variables and generated output. A checkpoint persists this data to a disk. It is possible to configure multiple checkpoints in a workflow.

Windows PowerShell Workflow provides multiple methods to implement a checkpoint. Whichever method is used to generate the checkpoint, Windows PowerShell will use the data in the latest checkpoint for the workflow to recover and resume the workflow if it is interrupted. If a workflow runs as a job (such as by using the AsJob workflow common parameter), Windows PowerShell retains the workflow checkpoint until the job is deleted (for example, by using the Remove-Job cmdlet).

Placing checkpoints

I can place checkpoints anywhere in a Windows PowerShell Workflow. This includes before and after each command or activity. The counter-balance to this sort of a paranoid approach is that each checkpoint uses resources. Therefore, it interrupts processing the workflow—often with perceptible results. In addition, every time the workflow runs on a target computer, it “checkpoints” the workflow.

So where are the best places to place a checkpoint? I like to place a checkpoint after a portion of the workflow that is significant, such as something that takes a long time to run. Or it might be a section of the workflow that uses a great amount of resources. Or even something that relies on a resource that is not always available.

Adding checkpoints

There are several levels of checkpoints that I can add to a Windows PowerShell Workflow. For example, I can add a checkpoint at the workflow level or at the activity level. If I add a checkpoint at the workflow level, it will set a checkpoint at the beginning and at the end of the workflow.

Workflow checkpoints are free

The absolutely, positively easiest way to add a checkpoint to a Windows PowerShell Workflow is to use the –PSPersist common parameter when calling the workflow.

The following workflow obtains network adapter, disk, and volume information:

workflow Get-CompInfo

{

  Get-NetAdapter

  Get-Disk

  Get-Volume

}

To cause the workflow to set a checkpoint, I call the workflow with the –PSPersist parameter, and I set it to $true as shown here:

Get-CompInfo -PSComputerName server1, server2 -PSPersist $true

When I run the workflow, a progress bar appears. It takes a few seconds due to the checkpoints. This progress bar is shown in the image that follows.

Image of command output

After the checkpoints, the workflow completes quickly and displays the gathered information. The following image shows the output and the command line that I used to call the workflow.

Image of command output

Checkpoint activity

If I use core Windows PowerShell cmdlets, they pick up an automatic –PSPersist parameter. I can then set a checkpoint for my workflow at the activity level. I use the –PSPersist parameter the same way that I do if I use it at the workflow level. To cause a checkpoint, I set the value to $true. To disable a checkpoint, I set it to $false.

In the workflow that follows, I set a checkpoint to occur after the completion of the first and third activities.

workflow Get-CompInfo

{

  Get-process -PSPersist $true

  Get-Disk

  Get-service -PSPersist $true

}

The workflow obtains process information, and then the workflow takes a checkpoint. Next, disk information and service information appear and the final checkpoint occurs. In the image that follows, the progress bar indicates a checkpoint in progress. But in the output pane, process information appears. This indicates that the Get-Process cmdlet ran prior to the checkpoint.

Image of command output

Using the CheckPoint-Workflow activity

The CheckPoint-WorkFlow activity causes a workflow to checkpoint immediately. I can place it in any location in the workflow. The big advantage of the Checkpoint-Workflow activity is that I can use it to checkpoint a workflow that does not use the core Windows PowerShell cmdlets as activities. This means that, for example, I can use a workflow that includes Get-NetAdapter, Get-Disk, and Get-Volume, and still be able to checkpoint the activity.

I need to use Checkpoint-Workflow because no –PSPersist parameter adds automatically to the non-core Windows PowerShell cmdlets. Here is my revised workflow:

workflow Get-CompInfo

{

  Get-NetAdapter

  Get-Disk

  Get-Volume

  Checkpoint-Workflow

}

AP, that is all there is to using checkpoints with Windows PowerShell workflow. Windows PowerShell Workflow Week will continue tomorrow when I will talk about more cool workflow stuff.

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

PowerTip: View PowerShell Console Host Information

$
0
0

Summary: View Windows PowerShell console host information.

Hey, Scripting Guy! Question How can I easily find information about the Windows PowerShell console host?

Hey, Scripting Guy! Answer Use the Get-Host cmdlet, and select the RawUI property from the InterhostUserInterface object:

(get-host).ui.RawUI

PowerShell Workflow for Mere Mortals: Part 5

$
0
0

Summary: Microsoft Scripting Guy, Ed Wilson, concludes his five-part series about Windows PowerShell Workflow.

 

Hey, Scripting Guy! Question Hey, Scripting Guy! I have a number of commands that I want to run against several remote servers. The commands include stuff that must happen prior to something else happening. But then, there are also some things that I would like to happen as fast as possible. Is this permissible? If so, do I have to write two different workflows?

—TB

Hey, Scripting Guy! Answer Hello TB,

Microsoft Scripting Guy, Ed Wilson, is here. This afternoon I am sipping an awesome cup of Oolong tea with a cinnamon stick, jasmine flower, and lemon grass. The flavor is just about perfect. In the background, I am listening to Ravel. Outside, the sky is dark and it is raining. The thunder seems to punctuate the music.

Note  This is the last post in a five-part series about Windows PowerShell Workflow for “mere mortals.” Before you read this post, please read: 

For more information about workflow, see these Hey, Scripting Guy! Blog posts: Windows PowerShell Workflow

Well TB, the good news is that you do not need to write two different workflows to enable parallel processing and sequential processing. Windows PowerShell Workflows are flexible enough to handle both in the same workflow.

Adding a sequence activity to a workflow

To add a sequence activity to a Windows PowerShell Workflow, all I need to do is use the Sequence keyword and specify a script block. When I do this, it causes the commands in the sequence script block to run sequentially and in the specified order.

The key concept here is that a Sequence activity occurs within a Parallel activity. The Sequence activity is required when I want commands to run in a particular order. This is because commands running inside a Parallel activity run in an undetermined order.

The commands in the Sequence script block run in parallel with all of the commands in the Parallel activity. But the commands within the Sequence script block run in the order in which they appear in the script block. The following workflow illustrates this technique:

workflow get-winfeatures

{

 Parallel {

    Get-WindowsFeature -Name PowerShell*

    InlineScript {$env:COMPUTERNAME}

    Sequence {

        Get-date

        $PSVersionTable.PSVersion } }

}

In the previous workflow, the order for Get-WindowsFeature, the inline script, and the Sequence activity is not determined. The only thing I know for sure is that the Get-Date command runs before I obtain the PSVersion because this is the order that I specified in the Sequence activity script block.

To run my workflow, I first run the PS1 script that contains the workflow. Next, I call the workflow and I pass two computer names to it via the PSComputerName automatic parameter. Here is my command:

get-winfeatures -PSComputerName server1, server2

The image that follows shows the Windows PowerShell ISE where I call the workflow. It also illustrates the order in which the commands ran this time. Note that the commands in the Sequence script block ran in the specified order—that is, Get-Date executed before $PsVersionTable.PSVersion. Also notice that they were in the same Parallel stream of execution.

Image of command output

Some workflow coolness

One of the cool things about this workflow, is that I ran it from my laptop running Windows 8. What is so cool about that? Well, the Get-WindowsFeature cmdlet does not work on desktop operating systems. Therefore, I ran a command from my laptop—a command which does not exist on my laptop, but it does exist on the target computers, Server1 and Server2.

Another cool workflow feature is the InlineScript activity. I am able to access an environmental variable from the remote servers. The InlineScript activity allows me to do things that otherwise would not be permitted in a Windows PowerShell Workflow. It adds a lot of flexibility.

TB, that is all there is to using Windows PowerShell Workflow and specifying Sequence information. This concludes Windows PowerShell Workflow week. Join me tomorrow when I will talk about Active Directory with Windows PowerShell.

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 

PowerTip: Find PowerShell Logging Info

$
0
0

Summary: Use a Windows PowerShell cmdlet to retrieve logged information about Windows PowerShell.

Hey, Scripting Guy! Question How can I easily find logged information about Windows PowerShell?

Hey, Scripting Guy! Answer Use the Get-WinEvent cmdlet and look for a LogName with powershell in the name:

Get-WinEvent -LogName *powershell*

Deciding How to Use PowerShell to Access AD DS

$
0
0

Summary: Microsoft Scripting Guy, Ed Wilson, talks about the decision points for deciding how to use Windows PowerShell to access Active Directory Domain Services.

Hey, Scripting Guy! Question Hey, Scripting Guy! I am a bit confused. I see various blogs and scripts on the Script Repository, and some always use a third-party snap-in to access Active Directory Directory Domain Services (AD DS). Others seem to use .NET Framework code to access AD DS, and still others are using a module that looks like it is part of Windows PowerShell. What is the best way to access AD DS?

—CB

Hey, Scripting Guy! Answer Hello CB,

Microsoft Scripting Guy, Ed Wilson, is here. This morning it is actually cool here in Charlotte, North Carolina. In fact, it is way cool because the Scripting Wife found a place on the Internet so she could order some chocolate covered Macadamia nuts. By the way, they go very well with Earl Grey tea with a cinnamon stick. The chocolate, the cinnamon, and the touch of bergamot combine to create an exquisite taste sensation. So, I am out on the lanai sipping tea, nibbling on chocolate covered Macadamia nuts and checking my email on my Surface RT, and I ran across this email to scripter@microsoft.com from CB.

Supportability—the big advantage

When comparing options for working with Active Directory Domain Services from within Windows PowerShell, one option stands above all the others: supportability. When I use the Active Directory module from Microsoft, it is supported. For me, this means a lot. So if something does not work out perfectly, I know it is supported.

I gain access to the Active Directory module in two ways. On a domain controller that is running at least Windows Server 2008 R2, I add the Active Directory management feature, and I have access to the Active Directory module. I can access it locally on the server, or I can use remoting or implicit remoting to access the cmdlets from my workstation. For more information about remoting, see Use PowerShell Active Directory Cmdlets Without Installing Any Software.

I can also install the Remote Server Admin Tools (RSAT) on my workstation. The version I install depends on the version of the operating system that I have on my workstation. For more information, see What's Up with Active Directory Domain Services Cmdlets?

Note If I install Active Directory Management Service for Windows Server 2008, I do not get access to the Active Directory module on the server. I must install the RSAT tools on my workstation for management purposes. For more information, see Install Active Directory Management Service for Easy PowerShell Access.

Usability

In my mind, the cmdlets from the Active Directory module are easy to use. They are a little quirky, but after I get used to the quirks, they simply make sense. Therefore, to create a new user in an organizational unit (OU) named testou in the Iammred.net domain, I type the following:

New-ADUser -Name mynewtestuser -Path 'ou=testou,dc=iammred,dc=net'
If I want to use the [adsi] type accelerator to create a new user, I type something like this:

$adsi = [adsi]"LDAP://dc=iammred,dc=net"

$de = $adsi.Create('user','cn=anothertestuser,ou=testou')

$de.setinfo()

One big problem with using this methodology (besides the fact that it is more typing and less intuitive), is the fact that tab expansion does not work properly. Therefore, some of the methods I want to use do not show up when I press the Tab key.

The advantage, of using the [adsi] type accelerator is that I can use it no matter what version of Windows AD DS is running in. I do not have to have the AD Management service installed, nor do I need a server running at least Windows Server 2008 R2. If my domain meets the minimum guidelines for using the Active Directory module, there is really no decision—I can use the module and use the cmdlets. They are easy, and they are powerful.

CB, that is all there is to using the Active Directory module. Join me tomorrow when I will talk about Windows PowerShell 3.0 in Windows 8. It is a way cool post, and a great way to continue your weekend. See you then.

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 


PowerTip: Use PowerShell to Get BitLocker Recovery Key

Weekend Scripter: Install Free PowerShell Remote Server Admin Tools

$
0
0

Summary: Microsoft Scripting Guy, Ed Wilson, talks about installing the free Remote Server Administration Tools for Windows PowerShell 3.0 in Windows 8.

Microsoft Scripting Guy, Ed Wilson, is here. This morning is an awesome morning. Our friends from Hamburg, Germany have been hanging out all weekend, and it has been a blast. We have spent a bit of time talking about Windows PowerShell training and some of the challenges related to that. We have also shared a love for tea. Yep. It has been a great weekend. Not only that, but the weather also cooperated—it has been sunny and not too humid.

One of the first things I do when I build a new computer running Windows 8, is install the Windows 8 Remote Server Administration Tools (RSAT) tools. After I do this, I gain access to many new and useful cmdlets that make it easy to administer everything from Active Directory Domain Services to Windows Software Update Services.

Getting the Windows 8 RSAT tools

For a free download of the tools, see Remote Server Administration Tools for Windows 8 on the Microsoft Download Center. There are two versions available on the download page: a 32-bit version and a 64-bit version. Finding the actual download is pretty easy—I click the big red Download button that is shown in the following image.

Image of menu

I can install the RSAT tools for Windows 8 on computers running Windows 8 or Windows 8 Pro. I cannot install them on my Windows Surface RT, but I can install them on my Windows Surface Pro.

The first thing I need to know is if my computer x86 or is it x64. The way that I usually find this out is to query an environmental variable as shown here:

PS C:\Users\ed.IAMMRED> $env:PROCESSOR_ARCHITECTURE

x86

Before I install the RSAT tools on my computer, I use the following script to to see how many cmdlets and functions are currently on my computer— I have 989.

PS C:\Users\ed.IAMMRED> gcm -CommandType cmdlet, function | measure

 

Count    : 989

Average  :

Sum      :

Maximum  :

Minimum  :

Property :

So I click the big red Download button to select my appropriate package.

Image of dialog box

Now, I have a choice. I can download the package and install it offline. Or if I choose Run, the file spools to a Temp folder, and it performs the installation from there. This works great if I have good Internet bandwidth, and if I do not anticipate needing to perform the installation again anytime soon. I will open the file, and after a quick security scan, the installation begins. Here is the dialog box I see:

Image of dialog box

While the RSAT installs, a progress bar tracks the percentage of completion. This is shown here:

Image of dialog box

The first thing I do after the installation is complete is use the Update-Help cmdlet to update the Help for the newly installed modules. This is shown here:

PS C:\Users\ed.IAMMRED> update-help -Module * -Force

After I install the RSAT tools, I check to see how many cmdlets and functions I now have. The number is 1757 as seen here:

PS C:\Users\ed.IAMMRED> gcm -CommandType cmdlet, function | measure

 

Count    : 1757

Average  :

Sum      :

Maximum  :

Minimum  :

Property :

Unlike previous versions of the RSAT tools, now when I install the tools, all of the modules and support tools automatically install. In previous versions, I had to go into Programs in Control Panel, select Turn Windows features on or off, and then scroll down to Remote Server Administration Tools to turn on each tool. Now, I only need to do this if I want to turn off a feature. This menu is shown here:

Image of menu

After the tools install and I have updated the Help, I can open the Windows PowerShell console (or the Windows PowerShell ISE) and begin to use the tools. The cool thing is that I can use the cmdlets from the Active Directory module to query a domain controller that is running Windows Server 2008. This is shown here:

PS C:\Users\ed.IAMMRED> Get-ADUser -Filter * -Server dc1 | select -Last 1

DistinguishedName : CN=anothertestuser,OU=Testou,DC=iammred,DC=net

Enabled           : False

GivenName         :

Name              : anothertestuser

ObjectClass       : user

ObjectGUID        : 36b19f4d-081b-4435-89cf-5979defe8c32

SamAccountName    : $9E1000-86BJ2L7MPKB4

SID               : S-1-5-21-1457956834-3844189528-3541350385-1481

Surname           :

UserPrincipalName :

But I can also use cmdlets that only exist in Windows Server 2012 as shown here:

PS C:\Users\ed.IAMMRED> Get-DhcpServerInDC

 

IPAddress            DnsName

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

192.168.0.152        wds1.iammred.net

Well, that is about it for today. Join me tomorrow as we begin a series written by Windows PowerShell MVP, Sean Kearney, about automating DiskPart. It is cool stuff.

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 

PowerTip: Find PowerShell Events and Levels

$
0
0

Summary: Use Windows PowerShell to find PowerShell related events and levels.

Hey, Scripting Guy! Question How can I find events that are related to Windows PowerShell in the event and diagnostic logs, and see the level for those events?

Hey, Scripting Guy! Answer Use the Get-WinEvent cmdlet and a wildcard character for LogName, select the logname and level properties, and make it easy by filtering only Unique entries:

Get-WinEvent -LogName *powershell* | select logname, level -Unique

Automating DiskPart with Windows PowerShell: Part 1

$
0
0

Summary: Honorary Scripting Guy, Sean Kearney, talks about using Windows Powershell to build scripts to automate DiskPart.

Hey, Scripting Guy! Question Hey, Scripting Guy! I know I can create a bootable USB key by using DiskPart, but is there any way to have it automated so the computer does the work for me?

—SH

Hey, Scripting Guy! Answer Hello SH,

Honorary Scripting Guy, Sean Kearney, here. I’m filling in for our good friend, Ed Wilson, who’s building some giant contraption in his backyard to hold his giant collection of bow ties. So he’s a bit “tied up.”

So the answer is absolutely, “Yes! Yes! Yes!” You can automate the creation of bootable memory keys. Having this ability is great if you’re using utilities like MDT 2012, and you need bootable media on the fly.

So I sat down and poked through my shiny new Surface Pro to dig for cmdlets to automate creating bootable partitions on USB.  There are so many new modules and cmdlets to choose from.

Then my jaw dropped. There were none (at least none that I could spy), and I wanted to fix that.

Creating a bootable USB key is pretty easy. Most of us could run this process with our hands behind our backs while singing a happy tune. The standard procedure for a bootable USB key is:

  1. Launch DiskPart as an Administrator.
  2. Use List Disk to find your USB key (or keys if you’re being efficient).
  3. Use Select Disk to choose your USB key.
  4. Clean (to wipe out the MBR and delete the partition entries).
  5. Run Create Partition Primary to create a new primary partition on the USB flash drive.
  6. Format FS=FAT32 Quick to lay down the file system as Fat32.
  7. Assign (to give our friend a drive letter).
  8. Active to make it bootable.

So if your USB key always came up as DISK 2, you might have a little text file called “bootme.txt” with the following commands:

  1. Select DISK 2.
  2. Clean.
  3. Create Partition Primary.
  4. Format FS=FAT32 Quick.
  5. Assign.
  6. Active.

You could happily run:

DISKPART /s .\bootme.txt

….and whoosh! All done.

But wouldn’t it be far nicer to have something a bit more dynamic with the ability to figure out most of the work for you? Then you actually could do this with a touch of your fingers!

The ironic thing about DiskPart is that it works great, but it doesn’t have a native way to export the information it has.

But I know of something that can help. Wait for it…

Starts with a “P”…

Has a cool theme song…

Yes! Of course! PowerShell can aid here! We can actually have Windows PowerShell create scripts for DiskPart and leverage the output of DiskPart to create newer scripts for it!

Sounds like magic doesn’t it? Nope. Just a feature of Windows PowerShell that has been used before to automate applications like HANDLE.exe from Sysinternals.

So our first challenge is to create a text file for DiskPart to literally “List the disks.”

We could cheat and simply type something in Notepad, but if we use a script (or better yet, build a function), the solution will be self-contained.

So first—oh mighty PowerShell—make me a text file. We could do something really fancy and elegant, but sometimes simplicity is best. Simple means easy to modify and easy to understand. Here we go:

NEW-ITEM –name listdisk.txt –itemtype file –force | OUT-NULL
ADD-CONTENT –path listdisk.txt “LIST DISK”

Now we can automate DiskPart with this new mini script. But we’ll want to capture the output:

$LISTDISK=(DISKPART /S LISTDISK.TXT)   

So what we’ve done here is capture all the output DiskPart was sending to the screen as a Windows PowerShell object. Now we can do all sorts of really neat stuff—like parse the data for what we want.

So the first thing we need to know from “LIST DISK” is, well, how many disks we’re looking at. Believe it or not, this is easier than you imagine. First off, the number of lines in the output is a built-in property:

$TOTALDISK=$LISTDISK.count

Now there are a lot of funky ways to figure this out. But honestly, all we have to know is how many of the lines in the output do not contain the information we want—the lines with the disk information. That number happens to be 9. (Yes, I smudged up my screen and counted 1….2…..3….ketchup stain.)

So we can use Windows PowerShell to calculate this:

$TOTALDISK=($LISTDISK.count)-9

But we have a ways to go. We need to find out the assigned number for the drive if it’s a USB flash drive…whether it’s pink or green.

But we’ll come back tomorrow and show more about how we can parse the information from DiskPart!

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

Sean Kearney (filling in for our good friend Ed Wilson),
      Honorary Scripting Guy, Windows PowerShell MVP
           …and good personal friend of the BATCHman

 

PowerTip: Use PowerShell to Automate Commands with DiskPart

$
0
0

Summary: Learn how to easily automate commands by using DiskPart.exe.

Hey, Scripting Guy! Question How can I use Windows PowerShell to automatically run DiskPart.exe commands that I use to make bootable keys?

Hey, Scripting Guy! Answer Store the commands you use in DiskPart.exe in a text file (runme.txt in this example), and run them automatically by adding the /s parameter:

DISKPART.EXE /s runme.txt

Note   You must run DiskPart.exe as Administrator.

Automating DiskPart with Windows PowerShell: Part 2

$
0
0

Summary: Honorary Scripting Guy, Sean Kearney, continues his series about using Windows Powershell to build scripts to automate DiskPart.

Hey, Scripting Guy! Question Hey, Scripting Guy! I saw yesterday that you can use Windows PowerShell to build a small script for DiskPart, but how can I make the information useful?

—SH

Hey, Scripting Guy! Answer Hello SH,

Honorary Scripting Guy, Sean Kearney, here. I’m filling in for our good friend, Ed Wilson. He appears to have overdone his tie house, and it’s bending under the weight. You could say it’s “bow”ing.

Enough of the bad puns. Yesterday we used Windows PowerShell to build a tiny DiskPart script and launch DiskPart to capture the output to count disks. Today we’re going to dive in a little deeper and get some useful information out of it. If we look at a sample screen output from DiskPart, we can identify some key features we’ll want.

Note  This is Part 2 in a series. If you are behind, read:

We’ll need the disk number. This is normally in sequence, but if a drive is removed, you’ll find that the values have gaps.

We’ll need the size. The reason for this is that I want to know if we have an 8 GB flash device or 500 GB flash device. If it’s larger than 64 GB (for my purposes), I’m going to presume that’s a removable hard drive.

But looking here, I don’t see anything showing me the device type. For that, there is a Detail command in DiskPart that we can leverage to show us that information. See the following output as an example:

Image of command output

You can see the Type for this particular device is USB. So we CAN get this information from the output from DISKPART. We just need to establish the pattern for the information.

Really we have a fairly easy pattern to work with on the LIST DISK output. We already know from the previous day that we can pull the number of disks from the output. So we only need to pull out the bottom number of lines. In Windows PowerShell if you access an array with element [-1] you will always access the bottom line of information.

So if you wanted to see the bottom line from DISKPART we can access that within the $LISTDISK object we created before

$LISTDISK[-1]

Image of command output

And then to access these individual members, we can produce deeper negative numbers:

Image of command output

What we need now is a way to access the data on each line. We could use some funky regular expressions, but we can also leverage some basic Substring() methods to pull out what we need. For each line, we can access the disk by selecting what appears to be the seventh character in the line (maybe some extra space?). To grab the information from the last line, we type:

$DiskID=$LISTDISK[-1].substring(7,5)

We of course should trim off any remaining white spaces after the output:

$DiskID=$LISTDISK[-1].substring(7,5).trim()

By using this same technique, we can grab the size of the actual media. It starts a little later down the same line. We’ll grab the number and GB (because in some cases, the output will be in KB or MB).

$SIZE=$LISTDISK[-1].substring(25,9)

In this case, I want to concatenate the numbers and spaces. A simple replace will meet this need:

$SIZE=$LISTDISK[-1].substring(25,9).replace(“ “,””)

What we need to do next is grab the disk type and the drive letter of the primary partition. Why the default letter? We’re going to design this so that all the information (including the drive letter that is assigned later) is available to use to send the output for XCOPY or Robocopy.

So we can take the information that we’ve obtained as an example and build a small DiskPart script to query details of that particular individual disk. The process will be similar to how we obtained the size and drive letters:

  1. Build a text file with the commands for DiskPart.
  2. Run DiskPart with the provided script, and capture the output.
  3. Parse the output and get the goodies we need.

First…to build the script for DiskPart to select a particular disk and obtain its details:

NEW-ITEM -Name detail.txt -ItemType file -force | OUT-NULL

ADD-CONTENT -Path detail.txt "SELECT DISK $DISKID"

ADD-CONTENT -Path detail.txt "DETAIL DISK"

$DETAIL=(DISKPART /S DETAIL.TXT)

Now we can use a similar process to parse out the data of the disk details:

First identify which line contains the Type: information. Yes. I sat there counting the lines on my screen to figure this out. (Does anybody have something to wipe off my fingerprints?)

$TYPE=$DETAIL[10].substring(9).trim()

Drilling down further, I find the drive letter for the first partition:

$DRIVELETTER=$DETAIL[-1].substring(15,1)

Now for fun, we’re going to grab some more specific details. The model of the drive also happens to be available and could be nice for output purposes:

$MODEL=$DETAIL[8]

Cool! With a little parsing we can grab the data we need and even build a simple DiskPart script with it.

But wait! How do we actually know the size? How do we go through and organize this into something more? Will Sean break into a song?

These answers and more in tomorrow’s episode of “Hey, Scripting Guy!” as we visit DiskPart and Windows PowerShell again in Part 3.

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

Sean Kearney (filling in for our good friend Ed Wilson),
      Honorary Scripting Guy, Windows PowerShell MVP
           …and good personal friend of the BATCHman

PowerTip: Show attached USB Drives with PowerShell

$
0
0

Summary: Use Windows PowerShell to show attached USB drives.

Hey, Scripting Guy! Question Is there an easy way with Windows PowerShell to show all drives that are connected via USB?

Hey, Scripting Guy! AnswerUse Get-WMIObject and query win32_diskdrive:

GET-WMIOBJECT win32_diskdrive | Where { $_.InterfaceType –eq ‘USB’ }

Or...

Write this as a query and pass it directly to WMI:

GET-WMIOBJECT –query “SELECT * from win32_diskdrive where InterfaceType = ‘USB’”


Automating DiskPart with Windows PowerShell: Part 3

$
0
0

Summary: Honorary Scripting Guy, Sean Kearney, continues his series about using Windows PowerShell to build scripts to automate DiskPart.

Hey, Scripting Guy! Question Hey, Scripting Guy! I saw yesterday how you could pull information from DISKPART with Windows PowerShell. I noticed the size of the disks was shown in GB or MB. Is there any way to convert that to tell the REAL size of the Disk?

—SH

Hey, Scripting Guy! Answer Hello SH,

Honorary Scripting Guy, Sean Kearney. I’m here filling in for our good friend, Ed Wilson. It seems that he is looking for some paint for his new Tie House. He’s asking if anybody has “tie dye.”

Alright,. on with DiskPart automation…

Note  This is Part 3 in a series. If you are behind, read:

If you were watching closely, the information we obtained for the size of the disk was delivered in the following fashion:

128GB

75MB

42KB

Although as a human, I can read that and understand that one is larger than the other, to make this useful we need to convert this to an actual integer. After it is converted, we can actually compare the size against a predefined parameter.

Fortunately, in Windows PowerShell, we have some built-in aliases for kilobytes (KB), megabytes (MB), and gigabytes (GB). So all we have to do is grab the final two characters, which will contain the multiplier, and use a Switch statement to quickly swap values. We can then grab the string with the numeric value for the physical size, and convert it to an integer. First off—how many characters are in the value?

$LENGTH=$SIZE.length

Now grab the last two characters, which will contain KB, MB, or GB:

  1. $MULTIPLIER=$SIZE.substring($length-2,2)

Now grab the remaining part at the beginning, which will be the numbers:

$INTSIZE=$SIZE.substring(0,$length-2)

Pass the $Multipier you found into a simple switch statement and swap the make believe world for the real world:

SWITCH($MULTIPLIER)

 {
  KB { $MULT = 1KB }
  MB { $MULT = 1MB }
  GB { $MULT = 1GB }
 
}

So now that we can simply multiply things and get the actual size for the disk, we’re going to enforce the result as an integer to make sure there’s no messy decimals in our output:

$DISKTOTAL=([convert]::ToInt16($intsize,10))*$MULT

Coolness! Now all we need to do is put all of this together into a function to return all of this as objects, and perhaps a bit more? Tune in tomorrow for our next episode of “Hey, Scripting Guy.”

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

Sean Kearney (filling in for our good friend Ed Wilson),
      Honorary Scripting Guy, Windows PowerShell MVP
           …and good personal friend of the BATCHman 

PowerTip: Use PowerShell to Get a List of All Volumes

$
0
0

Summary: Use Windows PowerShell to get a list of all volume drive letters and free space available.

Hey, Scripting Guy! Question How can I use Windows PowerShell to list all the drive letters and free space available?

Hey, Scripting Guy! Answer Use Get-WMIObject and query win32_logicaldisk to show all drive letters including
          network drives and CD ROMs:

GET-WMIOBJECT win32_logicaldisk

To view this as a table, add Format-Table:

GET-WMIOBJECT win32_logicaldisk | FORMAT-TABLE

Automating DiskPart with Windows PowerShell: Part 4

$
0
0

Summary: Use Windows PowerShell to build scripts to automate DiskPart.

Hey, Scripting Guy! Question Hey, Scripting Guy! Can we use Windows PowerShell to return information from DiskPart as an object?

—SH

Hey, Scripting Guy! Answer Hello SH,

Honorary Scripting Guy, Sean Kearney, here. I’m filling in for our good friend, Ed Wilson. He’s got tie’s everywhere! Ties all over his property! The problem is they’re running amok! You see, he’s turned into a “tie” fighter (and may the farce be with you).

Today we’re going to pull all of this together into a function that we’re going to call Get-DiskPartInfo. We will pull all of these scripts together to automatically parse through the disks in DiskPart, pull their data, and return it as a [pscustomobject].

Note   This is Part 4 in a series. If you are behind, please read:

So shall we get started? First we define our function, but we’ll attach the appropriate parameters and make this a true advanced function:

Function GET-DISKPARTINFO() {

[cmdletbinding()]

Param()

Now let’s add our first DiskPart script to get the number of drives:

NEW-ITEM –name listdisk.txt –itemtype file –force | OUT-NULL
ADD-CONTENT –path listdisk.txt “LIST DISK”
$LISTDISK=(DISKPART /S LISTTDISK.TXT)
$TOTALDISK=($LISTDISK.Count)-9          

Then we can loop through each disk, grabbing the DiskID and its physical size:

for ($d=0;$d -le $TOTALDISK;$d++)

{

$SIZE=$LISTDISK[-1-$d].substring(25,9).replace(" ","")
$DISKID=$LISTDISK[-1-$d].substring(7,5).trim()

Now that we have the DiskID, we can write a simple script for DiskPart to call up that disk and grab it’s Detail:

NEW-ITEM -Name detail.txt -ItemType file -force | OUT-NULL
ADD-CONTENT -Path detail.txt "SELECT DISK $DISKID"
ADD-CONTENT -Path detail.txt "DETAIL DISK"
$DETAIL=(DISKPART /S DETAIL.TXT)

And now with the Detail for that disk in hand, we run through our Detail parsing to pull the information we need from there:

$MODEL=$DETAIL[8]
$TYPE=$DETAIL[10].substring(9)
$DRIVELETTER=$DETAIL[-1].substring(15,1)

Now we take a few minutes to convert that drive size to a real integer that we can use to compare the size of the removable disk:

$LENGTH=$SIZE.length
$MULTIPLIER=$SIZE.substring($length-2,2)
$INTSIZE=$SIZE.substring(0,$length-2)

SWITCH($MULTIPLIER)
 {
  KB { $MULT = 1KB }
  MB { $MULT = 1MB }
  GB { $MULT = 1GB }
 }

$DISKTOTAL=([convert]::ToInt16($INTSIZE,10))*$MULT

Then all we need do now is wrap it up neatly as a custom object in Windows PowerShell:

[pscustomobject]@{DiskNum=$DISKID;Model=$MODEL;Type=$TYPE;DiskSize=$DISKTOTAL;DriveLetter=$DRIVELETTER}
}
}

Pull this advanced function together and you can turn the following information…

Image of command output

…into useful output like the following in Windows PowerShell:

Image of command output

Now we can even do something like this:

GET-DISKPARTINFO | WHERE { $_.Type –eq ‘USB’ –and $_.DiskSize -lt16GB }

Here’s where things are going to be interesting tomorrow. With all this information as an object, I’ll bet you’re wondering if I can go the next level, and automatically format those USB keys. Check in tomorrow for our final segment where we’ll tie all of this into that and automatically build a key from Microsoft Deployment Tootkit (MDT) 2012!

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

Sean Kearney (filling in for our good friend Ed Wilson),
      Honorary Scripting Guy, Windows PowerShell MVP
           …and good personal friend of the BATCHman

Changes to TechNet Library Scripting Node

$
0
0
I wanted to make you aware of some changes we’re making to the Scripting node in the Microsoft TechNet Library.  Summary The Scripting node in the TechNet Library has been renamed Scripting with Windows PowerShell , and will contain Windows PowerShell...(read more)

PowerTip: List Physical Drives with PowerShell

$
0
0

Summary: Use Windows PowerShell to list physical drives.

Hey, Scripting Guy! Question How can I use Windows PowerShell to get a list of physical drives?

Hey, Scripting Guy! Answer Use Get-WMIObject, query win32_logicaldisk, and filter with the DriveType property:

GET-WMIOBJECT –query “SELECT * from win32_logicaldisk where DriveType = ‘3’”

To check the drives on a remote computer, add the –ComputerName parameter.
For example, to list all physical drives and their free space on a machine called “ContosoWS1”:

GET-WMIOBJECT –query “SELECT * from win32_logicaldisk where DriveType = ‘3’”
–computername “ContosoWS1”

Viewing all 3333 articles
Browse latest View live