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

2013 Scripting Games Competitor’s Guide

$
0
0

Summary: The 2013 Windows PowerShell Scripting Games Competitor’s Guide is posted today.

Microsoft Scripting Guy, Ed Wilson, is here. Don Jones from PowerShell.org is back with us today with the 2013 Scripting Games Competitor’s Guide.

Scripting Games logo

 

Take it away, Don…

Welcome to the 2013 Scripting Games, now managed by PowerShell.org! This guide is designed to help you understand how the games work and what you can expect.

Important   See yesterday’s blog, 2013 Scripting Games Start April 22!, for information about the events, tracks, voting, and prizes.

Register

First up, you’ll need to register for the Games by logging on to http://TheScriptingGames.com. Note that there is no “www” on this URL. When you register, you’ll be asked to select a track. This is a one-time decision, and you may choose from:

  • None: You don’t want to compete, but you do want to grade other folks’ work by voting.
  • Beginner: You’ll be able to vote on all events, but you will be able to submit only one entry per event in the Beginner track.
  • Advanced: You’ll be able to vote on all events, but you will be able to submit only one entry per event in the Advanced track.

Caution   We ask that you not include any personally identifiable information in your entries. This includes your name, email address, or other contact information.

Games guidelines

Now, these are just ideas for you to consider. They’re not rules, and our judges won’t universally agree on every one of the ideas. So don’t think of this as a magic checklist that will make you win. You don’t even need to force yourself to do all of these things—but keep them in mind.

  • We love to see error handling, especially in the Advanced events. But we don’t like error suppression. That is, if an error occurs, we should see the error, or you should be doing something about it like logging it or displaying an alternate message.
    The exception: it’s okay to suppress an error that means “everything is going fine.” For example, you try to delete a file that doesn’t exist, and you get an error message. Well, that’s fine. At the end of the day, the file isn’t there, and that’s what you wanted. If you do choose to handle an error, make sure you’re doing so intelligently. Don’t wrap your entire code in a big Try{} block. Only wrap the commands that you anticipate will have an error, and Catch{} (and handle) that error.
  • We hate seeing people do more work than is necessary. For example, you shouldn’t ever prompt the user for a missing parameter. Use the Parameter() decorator in Windows PowerShell to mark the parameter as mandatory.
  • We love self-documenting scripts. That doesn’t just mean comments, although those are pretty awesome, too—especially comment-based Help. Using stuff like full command names and full parameter names (and no positional parameters) makes a script more self-documenting.
    Other examples are less obvious. Here’s one: if you’re accepting input arguments, do so via declared, named parameters, not by using the $args collection. $ComputerName (a named parameter) is a lot more meaningful than $args.
  • We hate inconsistency. In whatever you write, try to be consistent with what’s already in Windows PowerShell. A parameter named ComputerName is great; a parameter named ComputerNameS is not great. Nothing else in Windows PowerShell uses the plural, so you shouldn’t either.
  • We love scripts and commands that output objects and not formatted text. That means you shouldn’t embed a Format cmdlet in your script, nor should you use Write-Host in most cases. Exceptions are made by the name of your script or command; for example, we’d expect a command named Show-Info to show information on the screen, implying Write-Host is being used. A command named Get-Something, on the other hand, should output unformatted objects. We’ll pipe those to a Format command ourselves if we want them formatted.
  • We hate scripts that are hard to read. With scripts (as opposed to one-liners), focus on neat formatting. Avoid the backtick (`) as a line continuation trick because that little bugger is hard to see.
  • We love elegance. For example, a lot of folks think the expression "$computer cannot be reached" is easier and less complex than ("{0} cannot be reached" –f $computer)—even though these two expressions produce the same result. Both of those are prettier than ($computer + “ cannot be reached”). Just keep that in mind.
  • We hate redundancy…well, not in server farms, but definitely in script. For example, is all this really needed: Get-Service | Select-Object –Property @{n='Name';e={$PSItem.Name}}? Could you simply go for Get-Service | Select-Object –Property Name and get the same effect with less typing? We’re not saying this kind of thing will land you on a judges Worst list, but we know it’ll keep you off some judges Best lists.
  • We love functions that use [CmdletBinding()] and take advantage of the features it enables. For example, if you’re manually setting something like $VerbosePreference or $DebugPreference at the top of your script, you’re missing the point.
  • We hate scripts that pollute the global scope. It’s not yours. We don’t track mud into your house, don’t litter up our global scope with your variables.
    Exception: if you write a script module that politely adds global “preference” variables and then politely removes them when we unload it, that’s cool.

Don’t over obsess

In some event scenarios, we’ll give you an example of the expected output. It’s an example, not a mandatory deliverable. Basically, if you have all the right property names and the values look legitimate, you’re fine. They don’t need to be in the order we list them, and they don’t need to exhibit the exact same formatting, unless the event scenario calls out a specific requirement. In many cases, the example output is formatted to fit in a PDF file. It’s going to look different in the Windows PowerShell console, and we’re cool with that.

However, make sure that you meet the scenario requirements. If a requirement says to display a value in gigabytes, you’d better do it. Expect your Crowd Score to be pretty low if you display in bytes when the scenario explicitly asked for gigabytes.

Let’s be clear on something: if your goal going into the Games is to get on every judge’s Best list, you’re playing for the wrong reasons. If your goal is to get an amazing Crowd Score in every event, you’re probably going to be disappointed. This is a learning event.

Here’s another way to think about it: you’re going to have your script reviewed by dozens of peers, and possibly get some expert feedback from some of the biggest names in the industry. That alone is worth participating. The prizes are just icing on the cake!

DO NOT treat the previous list of guidelines as some kind of secret checklist for winning. It isn’t. They’re pretty good ideas in general, but they’re not the only good ideas. Like all rules they come with their own exceptions.

DO obsess about finding a clever, elegant, well-written solution to each problem. Knock our socks off! 

Try to not miss the point

Something different about the Games this year: You’ll notice that the only score you’ll receive is from your peers in the community—and we can’t tell them how to score you. Heck, some of them may not feel they’re even qualified to hand out scores, and a few of those might be right (more on that in a moment).

The score is nice—but it isn’t the point of the Games. The point is to think of creative approaches to real-world problems and to implement those approaches the best way you can.

Our expert judges will be picking their Best and Worst lists to highlight creativity, attention to detail, and overall sk1llz. Every judge will have different opinions, preferences, and techniques; and they’re all purely subjective. We’re not giving them any guidelines. So there’s no secret checklist for winning.

Our judges will blog about what they like and don’t like. And that is the real point of the Games: to learn.

Thanks to our presenting sponsors

Generous support from our sponsors makes the Games and all of PowerShell.org possible.
Please offer them your support and thanks.

Images of sponsor icons

GOOD LUCK!

~Don

Thank you to Don Jones and to the rest of the Windows PowerShell community for sharing this. Join me tomorrow when we will reveal two practice events for the 2013 Scripting Games.

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: Get Windows PowerShell Online Help

$
0
0

Summary: Use Get-Help and a switch to show the latest Windows PowerShell online Help in your browser.

Hey, Scripting Guy! Question How can I open and view the Windows PowerShell online Help in my Internet browser?

Hey, Scripting Guy! Answer Use the Online switch with the Get-Help cmdlet:

Get-Help Get-Process -Online

 

Beginner Practice for 2013 Scripting Games

$
0
0

Microsoft Scripting Guy, Ed Wilson, is here.  Today we have Don Jones, from www.powershell.org and a practice event for the Beginner category of the 2013 Scripting Games.

Scripting Games logo

This is a practice event. You will not submit this event to the actual Scripting Games, and no official judging will be available for this event. If you would like to post your solution for peer review, please do so in The Scripting Games forum on PowerShell.org or in another venue of your choosing. It is your responsibility to solicit peer reviews from the community; no judges or moderators are scheduled to provide reviews for this practice event.

Image of Dr. Scripto

Dr. Scripto is in a quandary. On one hand, he has a request to calculate the current uptime for a set of servers in his domain. On the other hand, he’d love to go see the new Michael Bay movie. Query uptime, or watch exploding robots?

Easy choice. While Dr. Scripto enjoys a wonderful motion picture, you get to figure out the uptime thing.

You’ve been given a list of server names and IP addresses in a text file, C:\Servers.txt. It contains one name or IP address per line. You need to write a command that displays each computer’s name (even if you were given an IP address, you must display the name) and the number of hours, minutes, and seconds the computer has been online since its last restart. Your output should consist of four properties with hours, minutes, and seconds broken out into their own individual properties.

You can be assured that all of the servers in the list are in the domain, and that you’ll have authority to query them. They’re all running Windows Server 2008 R2 or later, and they all have Windows PowerShell 3.0 installed. There are no firewalls or other blockages between you and those computers, and your command can assume that all of the servers are online and reachable. (If one isn’t, an appropriate error message should display, but it need not contain the failed computer name or IP address.)

Your command should be as concise as possible—a one-liner, if you think you can do it, although you’re welcome to use full command and parameter names for better readability. The output of whatever command you write must enable someone to pipe the output to a CSV file, XML file, or HTML file, if they so choose; but you do not need to provide those functions in the command you write.

Hint   There’s a commonly-used WMI class that contains the most recent computer start-up time. There are also event log entries related to total uptime.

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 

Advanced Practice for 2013 Scripting Games

$
0
0

Summary: Prepare for the Advanced category of the 2013 Scripting Games with this practice event.

Instead of a PowerTip today, we bring you Don Jones from www.powershell.org and the practice event.

Scripting Games logo

This is a practice event. You will not submit this event to the actual Scripting Games, and no official judging will be available for this event. If you would like to post your solution for peer review, please do so in The Scripting Games forum on PowerShell.org or in another venue of your choosing. It is your responsibility to solicit peer reviews from the community; no judges or moderators are scheduled to provide reviews for this practice event.

Image of Dr. Scripto

Dr. Scripto is in a quandary. On one hand, he has a request to calculate the current uptime for a set of servers in his domain. On the other hand, he’d love to go see the new Michael Bay movie. Query uptime, or watch exploding robots?

Easy choice. While Dr. Scripto enjoys a wonderful motion picture, you get to figure out the uptime thing.

You need to write a command that accepts one or more computer names by means of a parameter. That parameter must accept direct input or piped-in string values. Your command must prompt for computer names if none are provided when the command is run.

Your command output must include each computer’s name (even if you were given an IP address, you must display the name) and the number of hours, minutes, and seconds the computer has been online since its last restart. Your output should consist of four properties with hours, minutes, and seconds broken out into their own individual properties.

When your command runs, it should optionally display each computer name or IP address that it is about to connect to.

You can be assured that all of the servers in the list are in the domain, and that you’ll have authority to query them. They’re all running Windows Server 2008 R2 or later, and they all have Windows PowerShell 3.0 installed. There are no firewalls or other blockages between you and those computers, and your command can assume that all of the servers are online and reachable.

However, if an error occurs connecting to a computer, you should display an appropriate error message that includes the failed computer name or IP address. Your command must also provide a switch that causes failed computer names or IP addresses to be logged to a specified text file. If your command is run without that switch, no logging should occur.

If someone so chooses to do so, they should be able to pipe the output of your command to a CSV file, XML file, or HTML file—but you do not need to provide those features in the command you write.

Hint   There’s a commonly-used WMI class that contains the most recent computer start-up time. There are also event log entries related to total uptime.

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

Use PowerShell to Copy Files and Folders to a New Location

$
0
0

Summary: The Scripting Wife learns about using Windows PowerShell to copy files and folders in prep for the 2013 Scripting Games.

The days seem to start early, and the evening arrives later this time of year in Charlotte, North Carolina. I am sitting on the lanai drinking a cup of English Breakfast tea, and checking my email with my Microsoft Surface RT device. In my mind, it is a perfect way to ease in to the day, and my Surface is great for stuff like checking email and sending tweets.

I hear a sort of a thump, thump, thump, rattle, rattle, rattle sound and I look up. Strangely enough, I see nothing, so I go back to reading my email. But the sound persists. I get up from my swing and go into the house. I see the source of the noise: the Scripting Wife is digging through the front closet, and she has boxes, books, and other assorted paraphernalia spread out over the vestibule floor. In situations like this, I have learned to keep my mouth shut, and to wait for a natural opening.  

“I can’t find the flippin’ book,” the Scripting Wife exclaimed without looking up.

Not sure if this is a question, a remark, or even if it was directed at me, I decide to keep quiet.

“Well are you going to help?” she asked as she stood up.

“How can I help you, my peach?” I implored.

“You can help me find my autographed copy of Don’s book.”

I wait, knowing there is more to come.

“I saw your blog post about the upcoming 2013 Scripting Games, and I need to get back into shape by writing some code,” she stated.

“You are sort of like a scripting butterfly. You go here and there in random directions looking for nectar, but you never light for very long,” I paused to catch my breath.

“But I don’t need to know how to write scripts when I have my very own script monkey. Besides I just do this for fun,” she said.

“Well, I have no idea where you put your book, but I can help you for a few minutes if you wish,” I offered.

“I saw you reading your email, and I did not want to disturb you,” she said.

“Then why all the noise?” I asked.

“Maybe I figured if you came in here, then you were no longer reading your email and I could get you to help,” she posited.

“So what do you need to do?” I asked.

“Tell me about copying files. I have a bunch of pictures on my laptop that I want to copy up to the SAN so they do not get lost,” she said.

“Grab your laptop and come out to the lanai,” I instructed.

Using Copy-Item to copy files

“To copy a file from one folder to another, what cmdlet do you think you might use?” I asked.

Copy-File,” she posited.

“Close. It is called Copy-Item,” I said.

“Oh, yeah. Now I remember,” she said.

“Open your Windows PowerShell console, and use Copy-Item to copy any file from your C:\fso folder to your C:\fsox folder,” I said.

She thought for about a second and typed the following until she had a file selected:

Copy-I<tab><space>-p<tab><space>c:\fs<tab>\<tab> 

Next she typed the following:

-d<tab><space>c:\fsox\mylog.log<enter>

The completed command is shown here:

Copy-Item -Path C:\fso\20110314.log -Destination c:\fsox\mylog.log

When she pressed ENTER, an error arose. The command and the error message are shown in the following image.

Image of error message

“Well, that did not work,” she said, “I guess I do need to go find Don’s book after all.”

“No, I wanted to show you what happens if the destination folder does not exist,” I said.

“How can I avoid that problem?”

“You can use the Test-Path cmdlet. Type Test-Path and supply the path to the folder,” I said.

She typed the following into the Windows PowerShell console:

Test-P<tab><space>C:\fsox

The command is shown here:

Test-Path c:\fsox

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

Image of command output

“So the command says False. I guess that means the folder does not exist?” she asked.

“Yep. That is right. Now use the MD command and give it a path so that you create the new C:\fsox folder,” I said.

She typed the following:

MD<space>C:\fsox<enter>

The command is shown here.

md c:\fsox

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

Image of command output

“Now use the Up arrow and retrieve your previous Copy-Item command,” I said.

The Scripting Wife pressed the Up arrow a few times until the following command appeared:

Copy-Item -Path C:\fso\20110314.log -Destination c:\fsox\mylog.log

When the command appeared in the Windows PowerShell console window, she pressed ENTER to run the command. Nothing came back.

Easily copy multiple files by using Copy-Item

“That is OK, but I specifically want to copy my pictures, and I do not want to type a bunch of names. So how can I make Windows PowerShell copy my pictures for me?” she asked.

“To do that, use the Filterparameter and specify .jpg, which is the extension you use for your pictures. You will also need to specify the Recurse parameter,” I said.

She typed the following:

Copy-i<tab><space> -p<tab><space>c:\fso<space>-fi<tab><space>*.jpg<space> -d<tab><space> c:\fsox<space>-r<tab><enter>

The command is shown here:

Copy-Item -Path C:\fso -Filter *.jpg -Destination c:\fsox –Recurse

The newly copied files are shown in the following image.

Image of menu

“Cool,” she said as she bounded through the front door.

Scripting Games Prep Week will continue tomorrow when I will talk about Windows Management Instrumentation and obtaining basic computer information.

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 Copy Files

$
0
0

Summary: Learn how to use Windows PowerShell to copy files from one location to another.

Hey, Scripting Guy! Question How can I use Windows PowerShell to copy a file to a new location?

Hey, Scripting Guy! Answer Use the Copy-Item cmdlet and specify the path to the original file and a destination for the copy. In this example, file 20110314.log in the C:\fso folder is copied to folder C:\fsox with the new name mylog.log.

Note   The destination folder C:\fsox must exist.

Copy-Item -Path C:\fso\20110314.log -Destination c:\fsox\mylog.log

Weekend Scripter: Use PowerShell to Find the Version of Windows

$
0
0

Summary: The Scripting Wife learns about using Windows PowerShell to find computer hardware information in prep for the 2013 Scripting Games.

Microsoft Scripting Guy, Ed Wilson, is here. This morning did not start with a nice leisurely cup of tea on the lanai at home. Instead, it started by rushing around to get packed, loading up the vehicle, vying for a parking place at the airport, taking a shuttle from parking to the Charlotte terminal, standing in line for an hour for a security screen that was more intimate than my last physical exam, putting shoes and belt back on and repacking my suitcase, and standing in another really long line to buy an overpriced cup of warm milk with a shot of acidic coffee in it. Then another long line to board a really, really cramped airplane. Luckily, the Scripting Wife is with me, and she helps make the entire process a little more pleasant. Yep, we are finally on our way to Seattle for the Windows PowerShell Summit.

Scripting Wife uses WMI

After takeoff, I open my laptop and the Windows PowerShell console and start playing around. Before long the Scripting Wife is poking me in my shoulder.

“Yes,” I say.

“So I think this would be the perfect time for you to talk to me about using WMI with Windows PowerShell,” she stated.

“OK, good idea,” I said as I slid my laptop over to allow her to use it.

“So what now?” she asked.

“Well the first thing to know about WMI is that there are lots of WMI classes. They are also arranged into different namespaces, but we will not get into that right now. To find WMI classes, use the Get-CimClass cmdlet in Windows PowerShell 3.0,” I said.

“Well, that makes sense. So what do I do if I need to find the name of my operating system?” she asked.

“Why don’t you try it? Use the Get-CimClass cmdlet, and put osinto a pair of wildcard characters,” I suggested.

She typed the following:

Get-Cimc<tab><Space>*os*<enter>

The command is shown here:

Get-CimClass *os*

The command and the associated output are shown in the following image.

Image of command output

“Well, that did not do what I expected it to do,” she said.

“So, you have found out that WMI does not really have a class named OS, or anything similar to OS. What are you really looking for?” I asked.

“I want to know the version of Windows,” she said.

“The cool thing about Get-CimClass is that you can search for classes that contain a specific property. So why don’t you look for WMI classes that contain a property of version?” I suggested.

The Scripting Wife typed the following:

Get-Cimc<tab><space>-p<tab><space>version<enter>

The following is the command she created.

Get-CimClass -PropertyName version

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

Image of command output

“It is still a lot of stuff,” she complained.

“Well one of the things you need to know about WMI is that there are abstract and dynamic classes,” I began.

“And why do I need to know that?” she interrupted.

“Maybe you do not need to know all that, but keep in mind you want to use dynamic classes,” I began again.

“Why?” she asked.

“Because dynamic WMI classes go off and get information. So they are the ones that you want to use. The abstract classes are more used by developers,” I said.

“Well OK. So I only need to remember to use dynamic classes. I got it. Now what?” she said.

“The Get-CimClass cmdlet has a QualifierName parameter. You can specify that you only want dynamicWMI classes returned. It will give you a better output,” I said.

“Cool. So let’s do it,” she said energetically.

“Use the Up arrow to retrieve your previous command. Go to the end of the command and add the QualifierName parameter,” I said. “And don’t forget to use tab completion to help you.”

The Scripting Wife typed:

<uparrow><space>-q<tab><space>dynamic<enter>

Here is the command she created:

Get-CimClass -PropertyName version -QualifierName dynamic

The command and associated output are shown here.

Image of command output

“Cool,” she said. “So where do I find the version?”

“Look at the output. See the Win32_OperatingSystem?” I started.

“Oh yeah, I get it,” she said.

“Now use Get-CimInstance to retrieve the operating system information,” I said.

She typed the following:

Get-Cimi<tab><space>Win32_Op<tab><enter>

Here is the command:

Get-CimInstance Win32_OperatingSystem

Here is the command and the output from the command:

Image of command output

“Well ain’t that just special,” she said as she pushed the laptop back over to me. She then opened her Surface and began reading a book that she had downloaded.

I returned to my Windows PowerShell console, and tried to make sense of life.

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 Detect Mouse Type Used on Laptop

$
0
0

Summary: Use Windows PowerShell and WMI to detect the type of mouse that is being used on a laptop running Windows 8.

Hey, Scripting Guy! Question How can I find information about the type of mice that are being used in conjunction with my laptop that is running Windows 8?

Hey, Scripting Guy! Answer Depending on the mouse, you may be able to obtain the information by using the Get-CimInstance cmdlet and the Win32_PointingDevice WMI class. Select the HardwareType property.

Note  The following illustrates this technique on my laptop.

PS C:\> Get-CimInstance win32_POINTINGDEVICE | select hardwaretype

hardwaretype

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

ThinkPad UltraNav Pointing Device

Microsoft Wireless Laser Mouse 8000 (IntelliPoint)


Use PowerShell to modify WMI data such as drive label

$
0
0
Summary: The Scripting Wife learns how to use the CIM cmdlets and Windows PowerShell to assign a new drive label by modifying WMI data Weekend Scripter: Changing WMI information Microsoft Scripting Guy, Ed Wilson, is here. Well yesterday, after...(read more)

PowerTip: Use PowerShell to Find WMI Classes with a Specific Property

$
0
0

Summary: Use Windows PowerShell to find WMI classes that contain a specific property.

Hey, Scripting Guy! Question How can I use Windows PowerShell to help find a WMI class that contains a specific property?

Hey, Scripting Guy! Answer Use the Get-CimClass cmdlet in Windows PowerShell 3.0, and use the specific property name or a wildcard pattern to help you find the class:

Get-CimClass -PropertyName version

Get-CimClass -PropertyName *acl*

2013 PowerShell Scripting Games official kickoff

$
0
0
Summary: It is finally here -- the 2013 PowerShell Scripting Games official kickoff Microsoft Scripting Guy, Ed Wilson, is here. It’s here. It’s here. It’s here. Yep, the 2013 Windows PowerShell Scripting Games are finally here, and today is the official...(read more)

PowerTip: Use PowerShell to Keep Up-to-Date with the 2013 Scripting Games

$
0
0

Summary: Use Windows PowerShell to help you stay up-to-date with the 2013 Scripting Games.

Hey, Scripting Guy! Question How can I use Windows PowerShell to obtain an RSS feed of all 2013 Scripting Games content from the Scripting Guys?

Hey, Scripting Guy! Answer Use the Invoke-RestMethod cmdlet in Windows PowerShell 3.0 and specify the urifor the Scripting Guys 2013 Scripting Games RSS feed. Select the Title and the Pubdate, or even the Link to the blog posting.

Note  You can play with the RSS feed URL in Internet Explorer to ensure that you get the information you want to obtain.

$sg2013 = 'http://blogs.technet.com/b/heyscriptingguy/rss.aspx?tags=2013+scripting+games/'

Invoke-RestMethod -Uri $sg2013 | select title, pubdate

Use the AD DS Module to Find Computers with PowerShell

$
0
0

Summary: The Scripting Wife learns about querying Active Directory Domain Services with Windows PowerShell in prep for the 2013 Scripting Games.

Microsoft Scripting Guy, Ed Wilson, is here. Well yesterday I gave my first presentation (of three) at the PowerShell Summit happening here in Redmond, Washington. I thought my talk went really well, and several tweets I saw seemed to confirm that. I was also able to see some excellent presentations during the say. The Scripting Wife ran the registration desk, and so she was able to see everyone who is out here this week.

I am still on Charlotte time, and therefore am waking up at oh dark thirty each day. Surprisingly, the Scripting Wife has also been making early morning appearances for breakfast as well. Anyway, I am in the lobby sipping a cup of English Breakfast Tea (I did not bring any lemon grass or cinnamon sticks with me) and so it not my favorite cup of tea ever – but it is ok. It is strong, and helps to breakdown the croissants.

My eyes are closed as I visualize my two presentations I am making today at the PowerShell Summit. I open my eyes, and there she is – the Scripting Wife.

“If you are that sleepy, you need to go back upstairs and get some rest,” she began.

“Not sleepy, I am thinking about my presentations today,” I said.

“Oh that. Then you are not really doing anything, and so you can help me,” she said.

“What do you need,” I asked.

“I need to know how to query Active Directory,” she said.

“Say what,” I shockingly exclaimed. “Why do you need to query AD?”

“Well I think it is going to be in the 2013 Scripting Games, and so I figure I need to know how to query AD,” she said with emphasis.

“Well all right,” I said.

Use the ActiveDirectory module to query AD

“First let me fire up a Windows Server 2012 domain controller on my Windows 8 Hyper-V,” I said.

“I will take your word for it,” she said will as little interest as possible. “Just let me know when you are ready.”

I logged onto the Windows Server 2012 domain controller, and opened the Windows PowerShell console.

“Ok. It is up,” I said.

“So what do I need to do,” she asked.

“Well to get a listing of all computers in AD use the Get-ADComputer cmdlet. Specify a wildcard for the filter,” I instructed.

The Scripting Wife slid the laptop over to her, and typed the following:

Get-ADCo<tab><space>-f<tab><space>*<enter>

When she typed –f<tab> there was a slight pause, and the Windows PowerShell progress bar appeared as it imported the ActiveDirectory module. After that, the command proceeded quickly. The command appears here:

Get-ADComputer -Filter *

A command and the first computer from the output appears here:

PS C:\> Get-ADComputer -Filter *

DistinguishedName : CN=DC1,OU=Domain Controllers,DC=nwtraders,DC=msft

DNSHostName : dc1.nwtraders.msft

Enabled : True

Name : DC1

ObjectClass : computer

ObjectGUID : e1b57333-7155-4026-949d-82c35400a850

SamAccountName : DC1$

SID : S-1-5-21-1844339390-1396565537-2470583527-1001

UserPrincipalName :

Requesting a specific attribute

“Well that was painless. But what if I need to know the version of the operating system. How do I get that information? It does not seem to be in the output,” she asked.

“Well that is a very good observation. There are many more properties for each object in Active Directory Domain Services than are returned by a basic query. The reason for returning a subset of the attributes is for performance reasons. To request a specific property such as operatingsystem add the properties parameter. Why don’t you go ahead and try that,” I suggested.

The Scripting Wife thought for about 30 seconds and then she used the up arrow to retrieve her previous command. Next she added the –properties parameter and she added the operatingsystem attribute. This is what she typed:

<up arrow><space>-p<tab><space>operatingsystem<enter>

The command she created appears here.

Get-ADComputer -Filter * -Properties operatingsystem

The command and first output appears here.

PS C:\> Get-ADComputer -Filter * -Properties operatingsystem

DistinguishedName : CN=DC1,OU=Domain Controllers,DC=nwtraders,DC=msft

DNSHostName : dc1.nwtraders.msft

Enabled : True

Name : DC1

ObjectClass : computer

ObjectGUID : e1b57333-7155-4026-949d-82c35400a850

OperatingSystem : Windows Server 2012 Standard

SamAccountName : DC1$

SID : S-1-5-21-1844339390-1396565537-2470583527-1001

UserPrincipalName :

Using wildcards for properties

“That is pretty cool, but I do not like the output – it is rather crowded. I only want the name of the server and the name of the operating system. Can I get that,” she asked.

“But of course you can,” I said in my best Bela Lugosi imitation.

Ignoring the humorous voice, she plowed on, “So are you going to help me?”

“Well you cannot use a wildcard in the properties parameter, but when you use the Sort-Object cmdlet and the select-Object cmdlet you can use wildcards. So retrieve your previous command and pipeline it to Sort-Object and to Select-Object,” I said.

She thought for a minute, and this is what she typed:

<up arrow><space>|<space>sort<space>oper*<space>|<space>select<space>name,oper*<enter>

The command she created appears here:

Get-ADComputer -Filter * -Properties operatingsystem | sort oper* | select name, oper*

The command and the output appears here:

PS C:\> Get-ADComputer -Filter * -Properties operatingsystem | sort oper* | select name, oper*

name OperatingSystem

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

C7 Windows 7 Ultimate

C1 Windows 8 Enterprise

C2 Windows 8 Enterprise

SQL1 Windows Server 2012 Datacenter

DC1 Windows Server 2012 Standard

“That is pretty cool. Thanks. I am outta here, I think I just saw some PowerShell Summit people come in,” she said. And with that she was gone. I figured I would see her again when I got to building 40.

Join us tomorrow as the Scripting Wife continues studying for the 2013 Scripting Games.

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 Find WMI Classes Related to Disks

$
0
0

Summary: Use Windows PowerShell 3.0 to help find WMI classes related to disks.

Hey, Scripting Guy! Question How can I find WMI classes that will return information about disks on my local computer?

Hey, Scripting Guy! Answer Use the Get-CimClass cmdlet in Windows PowerShell 3.0. Use a wildcard character for the class name, and use the QualifierNameparameter to filter only dynamic WMI classes:

Get-CimClass -ClassName *disk* -QualifierName dynamic

Use PowerShell to Get Name and IP Address of Virtual Machines

$
0
0

Summary: The Scripting Wife learns to use Windows PowerShell to get networking information from all virtual machines running Hyper-V in prep for the 2013 Scripting Games.

Microsoft Scripting Guy, Ed Wilson, is here. It is the last day of the Windows PowerShell summit held in Redmond, Washington. One hundred Windows PowerShell gurus, enthusiasts, and MVPs from several countries have come together on the Microsoft campus to network and learn about the coolest Windows PowerShell ever. For the Scripting Wife and I, this will be a very, very long day. After a full day at the Windows PowerShell summit, I have a meeting with some teammates, and the Scripting Wife and I head to SeaTac for the red-eye flight back to Charlotte. Unfortunately, these days, it is nearly impossible for me to sleep on airplanes. Between the cramped seats, constant jostling, and random flashlight seatbelt checks, I just resign myself to try to get a bit of work done.

I am once again sitting in the lobby, sipping a cup of hot tea and thinking about making the most of our last day here with our friends, when along comes the Scripting Wife. She plops down in the seat beside me, and before I can say anything, she begins…

“I need to be able to find out some information from a Hyper-V server,” she exclaimed.

“My aren’t you becoming a geekette,” I said.

“Can it ,Script Monkey! I think I will need to know something about Hyper-V for the 2013 Scripting Games,” she said.

Use PowerShell to obtain basic Hyper-V information

“The good thing is that my laptop is running Hyper-V with Windows 8, and I installed the management module, so I can help you. What do you want to know?” I asked.

“Well for one thing, I think I want to know the names of the virtual machines, and maybe some networking stuff…I guess,” she said.

“Well that is pretty easy,” I said. “You can use the Get-VM Windows PowerShell cmdlet.”

The Scripting Wife did not hesitate, she immediately typed Get-VM and began to peruse the output. The command is shown here.

Get-Vm

“If you need to work with a single virtual machine, you can use the name to select just that virtual machine. To do that use the Name parameter,” I said. “Go ahead and return only the C1 virtual machine.”

“That makes sense,” she said as she began to type. Here is what she typed:

Get-VM<space>-n<tab>c1<enter>

The command is shown here:

Get-Vm -Name c1

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

Image of command output 

Finding additional virtual machine info

“Suppose I want to find out additional information about the virtual machine?” she asked.

“Well, you can pipe the virtual machine object to the Format-List cmdlet to see the other properties,” I said.

The Scripting Wife used the Up arrow to retrieve her previous command, and she added a pipeline and typed Format-List and a wildcard character. Here is what she typed:

<up arrow><space>|<space>Format-L<tab><space>*<enter>

The command is shown here.

Get-VM -Name c1 | Format-List *

“What is that NetworkAdapters property?” she asked.

“That property contains an additional object. To get inside the object, use the Select-Object cmdlet and the ExpandProperty parameter,” I said.

The Scripting Wife used the Up arrow and retrieved the previous command. She then erased the Format-List * portion of the command. She then added a pipeline character, used Select-Object, and expanded the NetworkAdapters property. The following is what she typed:

<up arrow><space>|<space>Select<space>-exp<tab><space>networkadapters<enter>

The command she created is shown here.

Get-VM -Name c1 | Select -ExpandProperty networkadapters

The command and the output are shown here.

PS C:\> Get-VM -Name c1 | Select -ExpandProperty networkadapters

Name IsManagementOs VMName SwitchName MacAddress Status IPAddresses

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

Network Adapter False c1 InternalSwitch 00155D003002 {Ok} {192.168...

“Well, that is pretty cool. The problem is that I only need the virtual machine name, the switch, mac address, and the IP address. Do I add the property parameter like I normally do with the Select-Object cmdlet?” she asked.

“Go ahead and try it,” I suggested.

When she typed the command, and pressed ENTER, the screen became covered with errors. The command and the associated errors are shown here.

Image of command output 

“Well that didn’t work,” she laughed.

“Yeah, I sort of wish it would, but it don’t. What you need to do is add a second Select-Object command and choose your properties,” I said.

The Scripting Wife thought for a few seconds, and began to type. The following is the command she created.

get-vm -Name c1 | select -ExpandProperty networkadapters | select vmname, macaddress, switchname, ipaddresses

“And I can do the same thing if I want this information from all of the virtual machines?” she asked.

“Absolutely. Why don’t you try it?” I said.

She thought for about a minute, then she pressed the Up arrow and retrieved her previous command. She then removed the –name c1 portion of the command and pressed ENTER. Here is the command she created.

get-vm | select -ExpandProperty networkadapters | select vmname, macaddress, switchname, ipaddresses

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

 Image of command output

“That is about all I need,” she said. “Make sure you get us checked out before you head to the summit,” she instructed.

I started to reply, but she was gone. When Windows PowerShell is involved, she is quick.

Join me tomorrow when the first events in the 2013 Scripting Games appear. WooHoo! The Scripting Games are here, the Scripting Games are here…almost. See you tomorrow.

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 Find Virtual Machine DVD Info

$
0
0

Summary: Use Windows PowerShell to find Hyper-V DVD information in Windows 8 or Windows Server 2012.

 
Hey, Scripting Guy! Question How can I use Windows PowerShell in Windows 8 or Windows Server 2012 to find Hyper-V virtual machine DVD disk information?

Hey, Scripting Guy! Answer Use the Get-VM cmdlet and pipe the output to the Get-VMDvdDrive cmdlet:

PS C:\> get-vm | Get-VMDvdDrive

VMName ControllerType ControllerNumber ControllerLocation DvdMediaType Path

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

c1 IDE 1 0 ISO C:\WINDOWS...

C2 IDE 1 0 None

DC1 IDE 1 0 None

sql1 IDE 1 0 None

 

2013 Scripting Games: Beginner Event 1

$
0
0

Summary: Dr. Scripto needs to gather all log files older than 90 days and move them to an archive location.

Microsoft Scripting Guy, Ed Wilson, is here. This is a day for the history books. Today is the first day of the 2013 Scripting Games as run by the Windows PowerShell community at www.powershell.org. Of course I am in full support mode for the Scripting Games, and I will also participate as a judge. The Scripting Wife is all set and ready to start on the Beginner Events. Without further ado, here is Beginner Event 1…

An Archival Atrocity

Dr. Scripto is in a tizzy! It seems that someone has allowed a series of application log files to pile up for around two years, and they’re starting to put the pinch on free disk space on a server. Your job is to help get the old files off to a new location.

The log files are located in C:\Application\Log. There are three applications that write logs here, and each uses its own subfolder. For example, C:\Application\Log\App1, C:\Application\Log\OtherApp, and C:\Application\Log\ThisAppAlso. Within those subfolders, the filenames are random GUIDs with a .log filename extension. After they are created on disk, the files are never touched again by the applications.

Your goal is to grab all of the files older than 90 days and move them to \\NASServer\Archives. You need to maintain the subfolder structure, so that files from C:\Application\Log\App1 get moved to \\NASServer\Archives\App1, and so forth.

Remember that the Scripting Games are being hosted at www.powershell.org, so head on over there to submit your entry.

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 

2013 Scripting Games: Advanced Event 1

$
0
0

Summary: Dr. Scripto needs to gather all log files older than 90 days and move them to an archive location.

Microsoft Scripting Guy, Ed Wilson, is here. This is a day for the history books. Today is the first day of the 2013 Scripting Games as run by the Windows PowerShell community at www.powershell.org. Of course I am in full support mode for the Scripting Games, and I will also participate as a judge. Without further ado, here is Advanced Event 1…

An Archival Atrocity

Dr. Scripto is in a tizzy! It seems that someone has allowed a series of application log files to pile up for around two years, and they’re starting to put the pinch on free disk space on a server. Your job is to help get the old files off to a new location.

Actually, this happened last week, too. You might as well create a tool to do the archiving.

The current set of log files are located in C:\Application\Log. There are three applications that write logs here, and each uses its own subfolder. For example, C:\Application\Log\App1, C:\Application\Log\OtherApp, and C:\Application\Log\ThisAppAlso. Within those subfolders, the filenames are random GUIDs with a .log filename extension. After they are created on disk, the files are never touched again by the applications.

Remember that the Scripting Games are being hosted at www.powershell.org, so head on over there to submit your entry.

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 

Scripting Wife Comments on Beginner Event 1

$
0
0

Summary: The Scripting Wife reveals her impressions of 2013 Scripting Games Beginner Event 1.

Hi everyone, I want to welcome you to the 2013 Scripting Games. This year the events were designed by the Windows PowerShell community, and the games are being run by the Windows PowerShell community. It is a very exciting and important year.

OK, so at first Beginner Event 1 did not make too much sense to me, so I had to read it multiple times before it dawned on me what was going on. You see, I am not a computer guru—I am more at home with Microsoft Excel than with Windows PowerShell. But Windows PowerShell is cool, and I have come to appreciate it over the years. In fact, I have found that some tasks are actually easier to do from Windows PowerShell than from the GUI (this is especially true for me in Windows 8).

Anyway, at first when I read this event, I was thinking event logs…hmmmm…I think I need to use Get-EventLog. I looked up the Help on Get-EventLog by doing the following:

help Get-EventLog

I looked through everything, but I did not find what I needed. Then it dawned on me that just because something says it is a log, does not mean it goes into an event log. These log files are really just files with a .log extension. I can treat them like they were text files. And I know how to work with text files.

Then I decided to look at some Hey, Scripting Guy! Blog posts about working with files for storage. I came up with this list of blogs. Next I decided to look at blogs that talk about working with dates and times, and I came up with this list of blogs.

By using these resources, I was able to come up with a solution to the Beginner Event 1. I spent a couple of hours reading and reviewing as part of the event, and I thought it was a fun process. I hope you will join in the spirit of the 2013 Scripting Games. You will be glad you do!

~Scripting Wife

Use PowerShell to Work with Windows Explorer

$
0
0

Summary: Microsoft PFE, Chris Wu, talks about using Windows PowerShell to work with the Windows Desktop through the Windows Explorer interface.

Microsoft Scripting Guy, Ed Wilson, is here. Today I have the privilege of welcoming back Chris Wu. Chris is a Microsoft premier field engineer (PFE) in Canada. If you are interested, see his other Hey, Scripting Guy! guest blogs. Now, here is Chris…

While playing with Windows PowerShell scripts, one of my favorite COM objects has been Shell.Application. I guess it is because I support Windows operating systems, and Windows Explorer is the primary way we interact with the system. Being able to script many of those tasks with ease is plainly awesome.

Many of our readers are probably familiar with the objects. Some may have even come across a script such as Pin and Unpin Applications from the Taskbar and Start Menu, or something similar, which utilizes this object to pin or unpin an application to the Taskbar or Start Menu.

 Image of command output

The script basically does it in a few steps:

  • Use the Verbs() method of a FolderItem object to get a list of verbs applicable to the target.
  • Search the verbs to find one with a name matching the expected action.
  • Execute the DoIt() method to invoke the verb.

The beauty of this technique is that the Verbs() method can return almost all actions found in the right-click context menu. If we compare the list of verbs to the context menu in Windows Explorer, we will find that the two lists are identical (and in the same order)—except for a few items that have submenus.

Image of menu

Although presented in uniform, the items in the list are actually implemented in various ways—as explained in Choosing a Static or Dynamic Shortcut Menu Method. Some of them are static verbs, others dynamic; some implement the IExecuteCommand interface, and some IContextMenu. Depending on the implementation, not all of these items can be called from Windows PowerShell. None-the-less, the previous pattern can be used to try to invoke the verbs without having to understand the implementation.

However, I wanted to invoke a verb in a more direct way to avoid pipeline processing. A little research on MSDN, and I found an InvokeVerb() method of a FolderItem object, which is described as “equivalent to selecting a command from an item’s shortcut menu.” More interestingly the Shell.ShellExecute() method has the vOperation parameter which is “set to one of the verb strings that is supported by the file.”

It seems that both of these methods can invoke a command directly. Unfortunately, they expect “verb strings,” which are language neutral strings that are different from the display names (they usually come from string resources embedded in localized DLL files), and it’s nontrivial to find some of the verb strings.

Although a large number of callable verb strings are registered with file association in HKEY_CLASSES_ROOT under the shell branch, some of them are hidden in the sea of CLSID registry keys. After a lot poking around and testing, following are several verbs that I’ve found useful. 

TaskbarPin and TaskbarUnpin 

Pin and unpin items to the Taskbar. These verbs are registered as a context menu handler for all items (but applicable only to some file types), and they can be called ShellExecute()however, not with InvokeVerb.

Image of menu

 

Image of menu

  $o.Namespace("c:\windows\system32").ParseName("rsop.msc").InvokeVerb("taskbarpin")

  $o.Namespace("c:\windows").ParseName("regedit.exe").InvokeVerb("taskbarunpin")

RunAs and RunAsUser

Run application elevated or as a different user. These are registered as static verbs for .exe, .bat, and .cmd files. RunAs is additionally available for .cpl files. RunAs works with ShellExecute() or with InvokeVerb(), but RunAsUser works only with ShellExecute().

Image of menu

  $o.Namespace("c:\windows\system32").ParseName("Firewall.cpl").InvokeVerb("runas")

  $o.ShellExecute("powershell.exe","-command ""get-date""","","runas","")

  $o.ShellExecute("c:\temp\test.bat","","","runasuser","") 

PinToStartScreen

Pin programs or folders to the start screen in Windows 8. This verb is registered as static verb for .exe files and folders, and it works with ShellExecute() or with InvokeVerb().

Image of menu

  $o.Namespace("c:\windows").Self.InvokeVerb("pintostartscreen")

  $o.ShellExecute("iexplore.exe","","","pintostartscreen","") 

Mount 

Mount .iso files in Windows 8 or Windows 7, or mount .vhd files in Windows 8. Mount is registered as static verb for .vhd and .iso files, and it works with ShellExecute() or InvokeVerb().

Image of menu

  $o.ShellExecute("C:\Downloads\Win7.iso","","","mount","")

  $o.Namespace("C:\Downloads").ParseName("iScsi.vhd").InvokeVerb("mount")

Eject

Eject a removable drive. Honestly, I don’t know how this verb is registered, but it works with InvokeVerb().

 $o.Namespace("D:\").Self.InvokeVerb("eject")

Change-Pin, Manage-BDE

Change the PIN or manage BitLocker for an encrypted drive. These are registered as static verbs for drives, and they can be invoked with ShellExecute() or InvokeVerb().

Image of menu

  $o.ShellExecute("C:\","","","manage-bde","")

  $o.Namespace("D:\").Self.InvokeVerb("change-pin")

cmd

Open a command window here for folders (in Windows 8 or Windows 7). Registered as a static verb for directories, this is an extended verb that doesn’t show in the context menu unless Shift key is held together with right-clicking. This verb works with ShellExecute()only.

Image of menu

 $o.ShellExecute("C:\Program Files (x86)","","","cmd","")

Because the list of verbs is dependent on item type (for example, file vs. folder, or the extensions .exe vs. .pdf) and applications installed on the computer, I am sure our readers will find more interesting verbs on their system. And before anybody points it out, I admit that there may be better ways to achieve some of the previous tasks. Taking the last one as an example, we can simply start a cmd.exe process and set the working directory to the target folder. But still, isn’t it sometimes cool to show off a seemingly confusing command that just works?

~Chris

Awesome job, Chris! Thank you for taking the time to share this with us today. Join me tomorrow when I have another guest blog from Chris. Tomorrow he will talk about improving the performance of arrays—you do not want to miss that.

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

Viewing all 3333 articles
Browse latest View live




Latest Images