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

PowerTip: Disconnect sessions to ISCSI target with PowerShell

0
0

Summary: Learn how to disconnect sessions to a specified ISCSI target with Windows PowerShell.

Hey, Scripting Guy! Question How can I use Windows PowerShell to disconnect sessions to a ISCSI target object?

Hey, Scripting Guy! Answer Use the Get-ISCSITarget cmdlet to retrieve the target, and then supply it as a node address for Disconnect-ISCSITarget, for example:

Get-IscsiTarget
$Tar = Get-IscsiTarget
Disconnect-IscsiTarget -NodeAddress $Tar.NodeAddress


PowerTip: Use PowerShell to disconnect virtual disk

0
0

Summary: Learn how to use Windows PowerShell to disconnect from a virtual disk.

Hey, Scripting Guy! Question How can I use Windows PowerShell to disconnect from a virtual disk?

Hey, Scripting Guy! Answer Use the Disconnect-VirtualDisk cmdlet and specify the friendly name, for example:

Disconnect-VirtualDisk -FriendlyName VirtualDisk01

PowerTip: Configure a client to listen for content requests by using PowerShell when powered on battery

0
0

Summary: Learn how to configure a client to listen for content discovery requests even when running on battery with Windows PowerShell.

Hey, Scripting Guy! Question How can I use Windows PowerShell to configure a client to listen for content discovery requests even when my computer’s running on battery?

Hey, Scripting Guy! Answer Open Windows PowerShell with elevated permissions, and use the Enable-BCServeOnBattery cmdlet. Here is an example:

Enable-BCServeOnBattery

The Doctor

 

 

PowerTip: Use PowerShell to configure BranchCache to run in local mode

0
0

Summary: Learn how to use Windows PowerShell to configure BranchCache to run in local caching mode.

Hey, Scripting Guy! Question How can I use Windows PowerShell to configure BranchCache to run in local caching mode?

Hey, Scripting Guy! Answer Open Windows PowerShell in an elevated prompt, and use the Enable-BCLocal cmdlet. Here is an example:

Enable-BCLocal

The Doctor

For the love of Pi

0
0

Summary: In honor of Pi Day today, we have a guest blog post written by PowerShell MVP, Doug Finke.

Image of apple pie with Pi character

Photo courtesy of Ed Wilson

It’s that time of year again when lovers of math, geometry, Albert Einstein, food, and Windows PowerShell can stop and reflect on that transcendental irrational number, Pi. It’s the ratio of a circle’s circumference to its diameter or “Hey, can I get a slice of that Pi?”.

Approximate Pi

The best we can do is approximate Pi, 22/7 (go ahead, type that into a PowerShell console). The first recorded algorithm for rigorously calculating the value of π was a geometrical approach using polygons, which was devised around 250 BC by the Greek mathematician, Archimedes.

Here we calculate π to 8 decimal places in only 13 iterations.

# http://www.craig-wood.com/nick/articles/pi-archimedes

function pi_archimedes($n) {
# Calculate n iterations of Archimedes PI recurrence relation

$polygon_edge_length_squared = 2.0
$polygon_sides = 4

if($n -gt 0) {
0..($n-1) | % {
$polygon_edge_length_squared = 2 – 2 * [math]::sqrt(1 – $polygon_edge_length_squared / 4)
$polygon_sides *= 2
}
}

$polygon_sides * [math]::sqrt($polygon_edge_length_squared) / 2
}

0..15 |% {
$result=pi_archimedes $_
[pscustomobject]@{
iteration = $_
sides     = [math]::pow(2, ($_+2))
result    = $result
error     = [convert]::ToDecimal(($result-[math]::PI).ToString(“N9″))
}
}

After iteration 13, the estimate of π starts getting worse. You can improve this by improving the precision of the calculation, which is left as an exercise to the reader.

iteration       sides      result                            error
———         —–        ——                             —–
0                        4       2.82842712474619    -0.313165529
1                         8       3.06146745892072   -0.080125195
2                      16        3.12144515225805    -0.020147501
3                      32       3.13654849054594  -0.005044163
4                      64       3.14033115695474    -0.001261497
5                    128       3.14127725093276   -0.000315403
6                    256       3.14151380114415     -0.000078852
7                    512       3.14157294036788   -0.000019713
8                 1024       3.14158772527996    -0.000004928
9                 2048       3.14159142150464    -0.000001232
10               4096       3.14159234561108    -0.000000308
11                8192       3.141592576545         -0.000000077
12             16384       3.14159263346325    -0.000000020
13             32768       3.14159265480759    -0.000000001
14             65536       3.14159264532122    -0.000000008
15            131072       3.14159260737572    -0.000000046

Food lovers

Let’s turn our attention to getting some Pi recipes, like apple and cherry.

Image of apple and cherry pies

Photo courtesy of Ed Wilson

Here’s a function, Get-Pi, that uses the Microsoft Bing API.

Note: You need a Bing API key to make it work.

function Get-Pi{
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline=$true)]
$q
)

Begin {
Add-Type -Assembly System.Web

$Key=$env:BingPicKey
if(!$env:BingPicKey) {
Throw ‘$env:BingPicKey needs to be set’
}

$Base64KeyBytes = [Text.Encoding]::ASCII.GetBytes(“ignored:$Key”)
$Base64Key = [Convert]::ToBase64String($Base64KeyBytes)
}

Process {
$query=[Web.HttpUtility]::UrlEncode($q + ‘ pi’)

$url = “https://api.datamarket.azure.com/Bing/Search/Web?`$format=json&Query=’$query'”

$r=Invoke-RestMethod $url -Headers @{ ‘Authorization’ = “Basic $Base64Key” }

$r.d.results| % {
[PSCustomObject][Ordered]@{
PiType = $q
Description=$_.description
Url = $_.Url
}
}
}
}

In action

Let’s get the Pi recipes for these classics.

echo cherry chicken apple | Get-Pi

Here is a modified version of the output.

PiType  Description
——  ———–
cherry  Bake an all-American Cherry Pie recipe from Food Network using fresh
cherry  Directions. Mix ingredients for filling. Place in pastry-lined pie p
cherry  Looking for a fruit dessert? Then check out this delicious pie with
cherry  Looking for cherry pie recipes? Allrecipes has more than 60 trusted
cherry  Summary. UPDATE 13 April 2014 … It rips through the Cherry Pi’s bo
chicken Get this all-star, easy-to-follow Chicken Pie recipe from Trisha Yea
chicken Use a prepared double-crust pie pastry to help achieve this easy, be
chicken Make your leftover chicken into the ultimate comfort food with a few
chicken Get this all-star, easy-to-follow Chicken Pot Pie recipe from Ree Dr
chicken I found this on another site. It is a fun and different way to serve
apple   A classic apple pie takes a shortcut with easy Pillsbury« unroll-fil
apple   I remember coming home sullen one day because we’d lost a softball g
apple   Winners of the Washington Apple Pi Photo Contest 2015 were announced
apple   This is the apple pie I’ve been making for years and if using Pillsbu
apple   For a touch of homegrown comfort, bake Bobby Flay’s classic Apple Pi

Happy Pi Day

From math to code to search APIs, that’s a quick tour for today. I encourage you to tour the Internet and read up on this magical number, and as a bonus, here is Get-BingPics on GitHub. It uses the same approach that we’ve seen, but the output is not text. Instead, the output is an HTML document with each image URL embedded in it. Click the following image to open a new window and see Get-BingPics in action.

Click the image to see animation of Get-BingPics results.

Thank you, Doug, for an excellent Pi Day blog post.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guy Forum. Also check out my Microsoft Operations Management Suite Blog. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

Control management pack updates between MS OMS and Operations Manager

0
0

Summary: Learn how to disable automatic management pack updates from MS OMS to Operations Manager and limit updates to a specific time window.

Hi all, Brian Wren here. I usually spend my time writing documentation for TechNet and Azure.com, but I’ve been hearing about an issue from a few customers that I wanted to address. We’re going to get some detailed documentation out on this, but a quick blog entry should suffice in the meantime.

When you connect a management group in System Center Operations Manager (SCOM) to Log Analytics in Operations Management Suite (OMS), several management packs are automatically installed in your management group. In addition to a core set of management packs to support the connection and basic data collection, others will be installed for different solutions that you’ve added to your OMS workspace. You can have a look at the entire list by doing a search for Advisor under Management Packs in the Administration workspace.

Screenshot of results for search for Advisor in Operations Management Suite workspace.

After initial installation, SCOM will regularly check OMS for updates to these management packs and automatically download and import them when they’re available. This works well in many environments because your integration between SCOM and OMS is automatically kept up to date with no effort on your part. This can be a problem though in environments that have low bandwidth or stringent change control processes. In these cases, you may want to turn off this automatic updating so that bandwidth is not consumed at peak hours and changes are not made outside your approved time window.

This update process is controlled by the following two rules.

  • Microsoft.SystemCenter.Advisor.MPUpdate

Updates the base OMS management packs. Runs every 12 hours by default.

  • Microsoft.SystemCenter.Advisor.Core.GetIntelligencePacksRule

Updates management packs for solutions in your workspace. Runs every 5 minutes by default.

You can easily disable automatic updates by creating an override to disable those two rules. You can reverse the override to enable them again and allow the updates to run, and you should enable them periodically to keep your management group up to date.

Override the update rules

You’re probably already familiar with creating an override in SCOM, but if not, I’ll go ahead and walk through it here.

Both of those rules are targeted at a class named Operations Manager Management Group (Microsoft.SystemCenter.ManagementGroup if you’re working under the covers). You can view them in the Operations Console with the following steps:

  1. Select Authoring workspace > Rules.
  2. Click Change Scope in the top-right.
  3. Select View all targets.
  4. Type management group to filter the list and select Operations Manager Management Group.

You should get a list of all rules targeted at the management group class, and you can see the two rules that interest us.

Screenshot of management pack objects scoped to Operations Manager Management Group.

Create an override to disable each rule with the following steps:

  1. Right-click the rule and then select Overrides > Override the Rule > For all objects of class: Operations Manager Management Group.
  2. Select the Enabled property and change its override value to False.
  3. Select an existing destination management pack to store the new override or create a new one.

Screenshot of an override that disables a rule.

You can follow the same process to set the value to True when you want to enable the rule again.

Since the MPUpdate rule runs every 12 hours, you will probably want to decrease this time if you’re going to enable it for a short period. Otherwise it may not have a chance to run during the time you have it enabled. For example, you might change its frequency to every 10 minutes (600 seconds) and enable it for an hour or so.

Screenshot of the Override Properties and the frequency parameter.

Automate the overrides

It’s not difficult to enable and disable the rules to control the MPUpdate process, but there are quite a few clicks required. It would be helpful if we could automate it with a single command. Eventually, I’d like to get this logic into a management pack so could control it entirely within SCOM. In the meantime, though, we should be able to use a Windows PowerShell script to control those overrides.

Russ Slaten posted a great script to create overrides a couple years ago that’s perfect for this. This script will allow you to specify the rule to override, the property and desired value, and the management pack to store the override. It will even create that management pack if it doesn’t already exist.

The following example uses that script to enable the MPUpdate rule and store the override in a management pack named OMS.Overrides.

CreateOverride.ps1 –ManagementServer scom01.contoso.com –ManagementPackID OMS.Overrides –WorkflowID Microsoft.SystemCenter.Advisor.MPUpdate –ContextID Microsoft.SystemCenter.ManagementGroup –PropertyName Enabled –PropertyValue True –Enforced False

Screenshot of results of a script that enables the MPUpdate rule and store the override.

Schedule the script

It would be helpful to schedule this script to run at certain times so we can have updates occur only during a certain time window. For example, we might want to have the updates disabled by default, enable them at 1 AM each night, and disable them at 2 AM.

As I mentioned before, I’ll hopefully get this functionality into a management pack at some point. A simple method, though, is to schedule the script to run as a scheduled task on a management server. You could technically run it on any machine with the Operations Manager console binaries installed, but a management server makes sense since that’s what the script has to connect to anyway.

You can create a scheduled task in Windows by using Task Scheduler, which you access from Administrative Tools. The Scripting Guys wrote a great blog post on exactly how to Use the Windows Task Scheduler to Run a Windows PowerShell Script, and that’s exactly the method I’ll use.

Because we need to run the script for each rule, and we need to give it a pretty long list of parameters, I created two additional scripts to encapsulate the long command lines.

Screenshot of parameters in the EnableOMSUpdates.ps1 script.

Screenshot of parameters in the DisableOMSUpdates.ps1 script.

That simplifies the argument that I need to pass to powershell.exe in the action for my schedule task. You can’t see it too well in the screenshot below, but the argument is –file “c:\scripts\DisableOMSUpdates.ps1″.

Screenshot of the –file "c:\scripts\DisableOMSUpdates.ps1" argument in the Edit Action dialog box for a scheduled task.

Create a scheduled task each for enable and disable to run at the appropriate time, and you’re ready to go.

Screenshot of the Enable and Disable scheduled tasks.

I invite you to follow me on Twitter and keep an eye on our new Monitoring documentation where we’ll be presenting a variety of scenarios using OMS and Operations Manager together.

Brian Wren

OMS Documentation Team

 

 

PowerTip: Find your version of PowerShell

0
0

Summary: Learn how to find your Windows PowerShell version easily.

Hey, Scripting Guy! Question How can I use Windows PowerShell to tell me what version of Windows PowerShell I am running?

Hey, Scripting Guy! Answer Use the $PsVersionTable automatic variable. To see the major, minor, build, and revision of Windows PowerShell, use the following:

$PSVersionTable.PSVersion

The Doctor

 

Using the new PowerShell ISE transcript tool

0
0

Summary: Ed Wilson, Microsoft Scripting Guy, talks about using the new Windows PowerShell 5.0 ISE Transcript tool.

 

One of my favorite features for Windows PowerShell has always been the transcript tool. I mean, it seems like it was made for Windows PowerShell … I guess it was. What am I talking about? Well, one of my favorite ways to spend time is plugging in various Windows PowerShell commands to see what they might do. Then I try to shorten them, make them leaner, or more powerful, or modify them to better suit my needs. Back when I used to do this on other systems, I would end up copying the command, and storing it in a notebook, or in a text file. With the Windows PowerShell transcript tool, I have not only a record of my commands, and errors they generate, but also the output that comes from the command. It is a great way to learn stuff about Windows PowerShell.

The problem, is that the Start-Transcript tool only worked in the Windows PowerShell console, and I have been using the Windows PowerShell ISE more and more … so I did like any good Windows PowerShell person would do, and I wrote my own transcript tool for the Windows PowerShell ISE.

But now … there is a Windows PowerShell ISE transcript tool built into Windows PowerShell ISE … beginning with Windows PowerShell 5.0 on my Windows 10 computer.

Start the PowerShell transcript

So, the first thing I do is open the Windows PowerShell ISE, and in the command pane, I type the command Start-Transcript. The command outputs the path to the transcript. This appears here:

PS C:\> Start-Transcript

Transcript started, output file is C:\Users\mredw\Documents\PowerShell_transcript.EDL

T.6VtWcOHE.20160329162630.txt

 

Now I type a command. I want one that will not take up too much space, so I select the last process in the collection of objects returned by the Get-Process cmdlet (gps is an alias for get-Process). This command appears here:

PS C:\> gps | select -Last 1

 

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id  SI ProcessName

——-  ——    —–      —– —–   ——     —  — ———–

293      18     5416      10536   116            2808   0 ZeroConfigService

 

Ok, now I stop the transcript. To do this, I use the Stop-Transcript cmdlet. This command once again outputs the path to the transcript file. This command and output appears here:

PS C:\> Stop-Transcript

Transcript stopped, output file is C:\Users\mredw\Documents\PowerShell_transcript.EDL

T.6VtWcOHE.20160329162630.txt

 

Note that the transcript file is the path to my documents folder in my profile, then the word transcript and a computer name, a bit of random number, and then the date and time. I could never remember all of tha, so I copy and paste it and try to open it in notepad. The result? An error. This appears here:

PS C:\> notepad C:\Users\mredw\Documents\PowerShell_transcript.EDL

T.6VtWcOHE.20160329162630.txt

T.6VtWcOHE.20160329162630.txt : The term ‘T.6VtWcOHE.20160329162630.txt’ is not

recognized as the name of a cmdlet, function, script file, or operable program.

Check the spelling of the name, or if a path was included, verify that the path is

correct and try again.

At line:2 char:1

+ T.6VtWcOHE.20160329162630.txt

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

+ CategoryInfo          : ObjectNotFound: (T.6VtWcOHE.20160329162630.txt:String

) [], CommandNotFoundException

+ FullyQualifiedErrorId : CommandNotFoundException

 

The problem is the path is so long, that it actually breaks into two lines. When I attempted to paste it back, I picked up a random break and the command failed. So, now I do a copy and paste again, but this time I hit backspace to remove the random break. Yeah, it works. Here is the log file:

HSG-3-29-16-01

A better way to handle this long log file path

A better way to handle this semi random long file name in a deep profile path, is to simply capture the returned output from the Start-Transcript command. Unfortunately, what returns is simply a string. This appears here:

PS C:\> $a = Start-Transcript

PS C:\> $a.GetType()

IsPublic IsSerial Name                                     BaseType

——– ——– —-                                     ——–

True     True     String                                   System.Object

 

PS C:\> $a

Transcript started, output file is C:\Users\mredw\Documents\PowerShell_transcript.EDL

T.wnH7glru.20160329163437.txt

 

When I wrote my transcript function, I also wrote a function called Get-TranscriptFile that parsed this string into a path that I could directly pass to notepad to open the transcript. I still have that function, but another cool cmdlet in Windows PowerShell 5 makes that a bit obsolete. That is because Windows PowerShell 5 includes a cool cmdlet called ConvertFrom-String that will create an object from a string. Here is an example:

PS C:\> Convertfrom-String -InputObject $a

P1 : Transcript

P2 : started,

P3 : output

P4 : file

P5 : is

P6 : C:\Users\mredw\Documents\PowerShell_transcript.EDLT.wnH7glru.20160329163437.txt

 

The part I want is the P6 property. The command appears here:

Notepad (Convertfrom-String -InputObject $a).p6

Sweet! So much easier than having to write my own functions and the like. PowerShell 5 for the win!

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. Also check out my Microsoft Operations Management Suite Blog. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy


Use PowerShell 5 to empty the recycle bin

0
0

Summary: Microsoft Scripting Guy Ed Wilson talks about using Windows PowerShell 5.0 to empty the recycle bin on Windows 10

 

It seems that now days when I talk to someone about Windows PowerShell 5.0 they get all excited and go on and on about Desired State Configuration (DSC). Now, I will agree, DSC is awesome. DSC rocks! Even on Windows PowerShell 4.0 DSC was great, but on Windows PowerShell 5.0 it is even better.

But … and this is huge … but, there is so much more in Windows PowerShell 5.0 than simply improvements to DSC. In fact, there is lots and lots of stuff in Windows PowerShell 5.0 that have been overshadowed by all the hoopla. AND, if you have Windows 10 (and more than 270,000,000 people are running Windows 10) then you already have Windows PowerShell 5.0.

It is time to shed some light on what I am calling the Windows PowerShell 5.0 stealth features.

A PowerShell cmdlet to empty the recycle bin

The recycle bin on Windows is awesome. It gives me a chance to say, “woops!” and then go get that file that I mis-moused. However, when the recycle bin takes up over a gigabyte of space on my hard drive, and when it contains tens of thousands of files, its uselessness quickly outweighs its utility. So, on a regular basis I empty the recycle bin – often when I am on a conference call that is dragging on, or when I am faced with writers block on some blog article. Needless to say, this is an ad hoc operation. I would like to do something more regular, so that when I need a deleted file, it is more easily found.

In the past, I have written all kinds of scripts to do this … including some in VBScript that even invoked SendKeys to deal with a user confirmation prompt that I could not get around. It worked, but it was a kludge. But now we have a way cool Windows PowerShell cmdlet to empty the recycle bin.

Testing out the empty recycle bin cmdlet

So I want to create some temporary files and then delete them. First I will create 25 temporary files (using the PowerShell 5 New-TemporaryFile cmdlet):

1..25 | % {New-TemporaryFile }

Now, I am going to look at the Temporary older to ensure that I have the temporary files there:

explorer.exe $([io.path]::GetTempPath())

Now I want to delete all of the files that are in my temporary folder:

dir $([io.path]::GetTempPath()) | Remove-Item -Recurse

Now it is time to see if they exist in the Recycle bin. So I use this bit of code to confirm:

New-Object -ComObject Shell.Application).NameSpace(0x0a).Items() |

Select-Object Name,Size,Path

 

Ok, now I clear the recycle bin:

Clear-RecycleBin -Force

Of course, I want to verify that the recycle bin is empty, so I use the following code to see that the recycle bin is empty:

(New-Object -ComObject Shell.Application).NameSpace(0x0a).Items() |

Select-Object Name,Size,Path

 

Sweet! And no SendKeys was required.

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. Also check out my Microsoft Operations Management Suite Blog. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

Use PowerShell 5.0 to create temporary files in the temp folder

0
0

Summary: Microsoft Scripting Guy Ed Wilson talks about using Windows PowerShell 5.0 on Windows 10 to create temporary files in the temporary folder.

 

Sometimes it is the little things that make life easier. You know, like a cereal bar … it’s not like a major technological breakthrough but it is much more convenient than getting a bowl of milk and opening a box of cereal and dumping it in the bowl. Or a peanut butter cup is easier to use than getting two bars of chocolate and a jar of peanut butter … neater too.

Well in Windows PowerShell 5.0 there are lots of these stealth features that make life easier and simpler for me than even Windows PowerShell 4.0. I am talking about Windows PowerShell 5.0 on Windows 10, because the downlevel package will not have all the API’s available for some of these way cool cmdlets.

Creating a temporary file in the temp folder

From time to time, I need to create a temporary file. In the old days I would create a file and give it a name that I would calculate. This wasn’t random, but it worked pretty good if I tested to ensure that the file did not already exist, and if it did exist, then I would delete it and create the file. As you might surmise, that was about three lines of code … not as bad as in the VBScript days, but still it was boring to do. I even wrote my own create a temporary file function to relieve some of the tedium.

Later, I was reading through the .NET Framework SDK and I came across a static method of the System.IO.Path class. It was called GetTempFileName. This was a bit confusing because at first everytime I called it to get a temporary file name, and then I used that temporary file name to create a temporary file, I would get an error … the call worked, but it generated an error. Later, I figured out that the GetTempFileName static method was actually misnamed, and should have been named CreateTempFile because that is what it does. I generates the temp file name AND creates the temporary file. So when I was calling the method to get the temp file name it created the file. Then when I attempted to use the temp file name to create the file … well an error occurred.

The really easy to create a temp file using PowerShell 5

The really easy to create a temp file is to use Windows PowerShell 5.0 on Windows 10 … because there is a New-TemporaryFile cmdlet. This is really simple:

PS C:\> New-TemporaryFile

 

 

Directory: C:\Users\mredw\AppData\Local\Temp

 

 

Mode                LastWriteTime         Length Name

—-                ————-         —— —-

-a—-        3/31/2016   8:05 PM              0 tmp36BB.tmp

 

Of course, this does not do a whole lot of good because while I have a temp file, I cannot really access it very easily because I don’t know the name and path. Well, I can figure out the path perhaps, but not the file name. So the better way to do this is to capture the output. This appears here:

PS C:\> $tmp = New-TemporaryFile

$tmp | fl *

 

 

PSPath            : Microsoft.PowerShell.Core\FileSystem::C:\Users\mredw\AppData\Local\Temp\tmpBADC.tmp

PSParentPath      : Microsoft.PowerShell.Core\FileSystem::C:\Users\mredw\AppData\Local\Temp

PSChildName       : tmpBADC.tmp

PSDrive           : C

PSProvider        : Microsoft.PowerShell.Core\FileSystem

PSIsContainer     : False

Mode              : -a—-

VersionInfo       : File:             C:\Users\mredw\AppData\Local\Temp\tmpBADC.tmp

InternalName:

OriginalFilename:

FileVersion:

FileDescription:

Product:

ProductVersion:

Debug:            False

Patched:          False

PreRelease:       False

PrivateBuild:     False

SpecialBuild:     False

Language:

 

BaseName          : tmpBADC

Target            : {}

LinkType          :

Name              : tmpBADC.tmp

Length            : 0

DirectoryName     : C:\Users\mredw\AppData\Local\Temp

Directory         : C:\Users\mredw\AppData\Local\Temp

IsReadOnly        : False

Exists            : True

FullName          : C:\Users\mredw\AppData\Local\Temp\tmpBADC.tmp

Extension         : .tmp

CreationTime      : 3/31/2016 8:07:31 PM

CreationTimeUtc   : 4/1/2016 12:07:31 AM

LastAccessTime    : 3/31/2016 8:07:31 PM

LastAccessTimeUtc : 4/1/2016 12:07:31 AM

LastWriteTime     : 3/31/2016 8:07:31 PM

LastWriteTimeUtc  : 4/1/2016 12:07:31 AM

Attributes        : Archive

 

More than likely, I want the fullname property because it contains the path to the file as well as the file name and extension. It will be easy to use. This appears here:

PS C:\> $tmp.FullName

C:\Users\mredw\AppData\Local\Temp\tmpBADC.tmp

 

So, now I can use Out-File to write to the file. This appears here:

Get-Process | Out-File $tmp.FullName

notepad $tmp.FullName

 

Or, I can redirect to the file. This appears here:

Get-Service >> $tmp.FullName

notepad $tmp.FullName

Remove-Item $tmp.FullName -Force

 

When I am done, I want to use Remove-Item to delete the temporary file so that I keep things neat and tidy.

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. Also check out my Microsoft Operations Management Suite Blog. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

Next steps for the official PowerShell documentation

0
0

Summary: Learn about changes that we’ve already made for PowerShell content and what’s planned for the near future.

Hello scripters!

My name is Don Gill, and I am the new documentation manager for Windows PowerShell. With the 2016 PowerShell and DevOps Summit quickly approaching, I thought it would be a fantastic opportunity to introduce myself to the PowerShell community and share some changes that we are putting in place to help you stay more connected with the PowerShell development team, share your feedback and suggestions, and even contribute directly to improving the PowerShell documentation.

While I am new to PowerShell, I’ve been with Microsoft for nearly 17 years. In that time, I’ve had the pleasure of working in roles across developer support, technical evangelism, and community outreach before ultimately finding my passion — technical content development.

When I recently saw the opportunity to join the PowerShell content team, I jumped at the chance because I could clearly see that the space has two of the three elements that are critical to deliver amazing documentation experiences:

  • A dedicated community of users learning and freely sharing best practices
  • A great development team with a strong technical vision
  • A non-proprietary authoring platform that enables everyone to contribute to an ever improving set of guidance

Any guesses on the missing critical element?

Windows PowerShell Documentation is moving to open publishing

Last November, the PowerShell content team ran a small pilot to publicly share the PowerShell Desired State Configuration (DSC) content source in the open MarkDown format though GitHub. The question we had was simple — given the opportunity, would the PowerShell community engage and directly contribute to improving technical content? I’m pleased to announce that the results have proven better than expected.

Since going live in early November, there have been nearly 600 commits and more than 200 pull requests from 34 different contributors in our GitHub repository for DSC and WMF 5.0. Contributions ranged from the submission of entirely new topics from the likes of PFE Ashley McGlone, to critical technical refinements from customers like Daniel Scott-Raynsford and Aleksandar Nikolić, and a plethora of legit fixes to code examples and typos from many, many others. Issues raised by customers like Jason Morgan, Jeremy Murrah, and Arie Heinrich have driven lots of internal discussion within our team and ultimately put us on the path to making smarter decisions on how to approach complex concepts in a simpler more effective way.

While it will take time to completely shift over to this model, I intend to open the entirety of the Windows PowerShell content to the community through open publishing on GitHub. If you want to help make a lasting contribution to the PowerShell community, PowerShell documentation is a great place to start.

What you can contribute to now

If you’re ready to kick the tires, contribution to PowerShell content is easy.

Screenshot of the Contribute link in an article.

In the upper-right corner of every DSC topic, there is a Contribute link. When you select it, you go to our GitHub repository and the underlying source Markdown file of the content. Within GitHub, you can propose additions and updates to the content itself as well as changes and improvements to associated code and script examples directly in the content source file. After the proposed changes are accepted by my team, they are rolled together and republished on a daily basis. As a contributor, you are given full authoring contribution credit on every topic you help improve.

If you’re not already familiar with GitHub or the Markdown format or would like more detailed instructions about how to contribute, I’d encourage you to take a look at the contribution guidelines as a primer.

In the coming weeks and months, we’ll be shifting more and more of our Windows PowerShell content to this open publishing system and will be announcing its availability through the @PowerShell_Team Twitter account. Next up on the list for open publishing is the conceptual content within “Scripting with Windows PowerShell”. Stay tuned!

Lastly, if you are planning to attend the PowerShell and DevOps Summit, feel free to look me up and say, ‘Hi’. I’ve dusted off my old twitter account (@dongill) just for the occasion. I’d love to meet you and hear your perspectives on how we can improve the overall help and documentation experience for Windows PowerShell.

Don Gill

Windows PowerShell

PowerTip: Create a nested PowerShell custom object

0
0

Summary: Learn how to create a nested PowerShell custom object.

Hey, Scripting Guy! Question How do I create a nested PowerShell custom object to store layers (nested) of information?

Hey, Scripting Guy! Answer Use a hashtable with the PSCustomObject type accelerator, and specify PSCustomObject as the value to the Property Name (Key):

[PSCustomObject]@{
PropertyName = [PSCustomObject]@{ NestedPropertyName = ‘NestedPropertyValue’ }
}

7610.Dr.ScriptoForTips

PowerTip: Get Azure Virtual Machine Diagnostics by using PowerShell

0
0

Summary: Use the Azure Resource Manager cmdlets to retrieve diagnostic data within Azure Resource Manager virtual machines.

Hey, Scripting Guy! Question Our QA department was asking a very specific question that I didn’t know how to answer. Is there anything in an Azure virtual machine (VM) to show the quality of the boot and its startup?

Hey, Scripting Guy! Answer Maybe this will help. You can access the boot diagnostics data with a single cmdlet. To retrieve the data for a single machine, use the Get-AzureRmVMBootDiagnosticsData cmdlet and add a parameter to target whether the machine is a Windows VM or Linux VM. Here is an example:

Get-AzureRmVMBootDiagnosticsData -ResourceGroupName HSG-AzureRG -Name HSG-Linux1 -Linux

The Doctor

Retrieve Azure Resource Manager virtual machine properties by using PowerShell – Part 3

0
0

Summary: Identify properties for the operating system of a virtual machine.

Hey, Scripting Guy! Question Can you show me how to identify the properties for the operating system so that I can duplicate a virtual machine?

Hey, Scripting Guy! Answer Honorary Scripting Guy, Sean Kearney, is here with a little more Azure and PowerShell for you. Today we’re going to examine the properties that tell us the template to use for the operating system.

Again, none of this is hidden in the portal. However, if you look, you won’t see the exact details that PowerShell will want for virtual machines.

In fact, when we look at the portal, it doesn’t even identify the version of Linux. It just says “Linux,” which really isn’t all that helpful.

Screenshot of the properties which indicate an operating system.

As we did yesterday, we’ll store the properties of the virtual machine in an object.

$VM=Get-AzureRMVM –Name HSG-Linux1 –ResourceGroupName HSG-AzureRG

The particular set of properties that we need are actually stored under a property known as StorageProfile.

$VM.StorageProfile

Buried within the StorageProfile object is a very useful property named ImageReference.

$VM.StorageProfile.ImageReference

Screenshot that shows the publisher, offer, SKU, and version information.

By using PowerShell, I can identify three of the key pieces that I will need for a virtual machine. It’s also important to note that this is common to both Linux and Windows deployments.

After I store the publisher, offer, and SKU properties, I can use this to obtain the data that I will need next week to create a virtual machine: the operating system image. We use the Get-AzureRMVMImage cmdlet for this.

To get the images, we need four pieces of Information.

  • Publisher
  • Offer
  • SKU
  • Location

We have the first three:

$Publisher=$VM.StorageProfile.ImageReference.Publisher
$Offer=$VM.StorageProfile.ImageReference.Offer
$Sku=$VM.StorageProfile.ImageReference.Sku

The location is just another available property from the virtual machine. It’s not even buried.

$Location=$VM.location

With this information, we can now access a list of virtual machine images that can be used to create a twin of this virtual machine that uses the same operating system.

Get-AzureRmVMImage -PublisherName 'Canonical' -Offer 'UbuntuServer' -Skus '14.04.4-LTS' -Location 'eastus'

Oh, how do we sort this mess out? It appears that we have too many versions to choose from. If you’d like the latest one, we can sort by the version number.

Screenshot that shows versions of Ubuntu images.

Get-AzureRmVMImage -PublisherName 'Canonical' -Offer 'UbuntuServer' -Skus '14.04.4-LTS' -Location 'eastus' | Sort-Object Version

Then, we can grab the newest one from the bottom of the pile!

(Get-AzureRmVMImage -PublisherName 'Canonical' -Offer 'UbuntuServer' -Skus '14.04.4-LTS' -Location 'eastus' | Sort-Object Version)[-1]

Pretty neat, eh?

Come on by tomorrow when we discuss how to identify the resource group and other properties that are attached to the virtual machine!

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

Until then, always remember that with Great PowerShell comes Great Responsibility.

Sean Kearney
Honorary Scripting Guy
Cloud and Datacenter Management MVP

 

PowerTip: List Azure Resource Manager resources assigned to a resource group by using PowerShell

0
0

Summary: Use the Azure Resource Manager cmdlets to show resources that are assigned under a resource group.

Hey, Scripting Guy! Question I looked at the console for Azure Resource Manager and can see all the resources for a particular resource group. Is there a way to see that by using PowerShell?

Hey, Scripting Guy! Answer There sure is! Just use the Get-AzureRMResource cmdlet and filter on the ResourceGroupName property. Here’s an example:

Get-AzureRmResource | where { $_.ResourceGroupName -eq 'HSG-AzureRG' } | Format-Table

 

The Doctor


Retrieve Azure Resource Manager virtual machine properties by using PowerShell – Part 4

0
0

Summary: Find storage groups by using PowerShell.

Hey, Scripting Guy! Question Could you lend me a hand? I’m trying to find properties, like the current storage group that a virtual machine uses, in Azure Resource Manager, and I’m having some difficulty.

Hey, Scripting Guy! Answer Honorary Scripting Guy, Sean Kearney, is here to get you the help that you need. Storage groups? No problem.

The first time that I went to tackle this one, I was stumped. Here’s why.

I went to look at the virtual machine disks in the portal, and I saw something along the lines of this.

Screenshot of the URI of the storage group in the portal.

For the storage group, all I got was an URL! But, wasn’t the storage group named hsgstorageaccount?

In fact, it is. But as it turns out, everything you need is sitting right there. To access the storage group when you create a virtual machine by using PowerShell, what you really need is the URL to the storage account.

So, although I can copy that from the portal and take the piece that I need, it’s better to give you a programmatic solution to automatically generate the data, right? Unless you get paid by the mouse click, in which case, more power to you.

To achieve this, we need to get the properties from the OSDisk object. The storage account URL is actually a part of that.

First as always, grab the properties of the virtual machine in question:

$VM=Get-AzureRMVM –Name HSG-Linux1 –ResourceGroupName HSG-AzureRG

The part that we’re looking for is a part of the StorageProfile object:

$VM.StorageProfile

Screenshot that shows the ImageReference and OsDisk.

Without even looking hard, we can see an object that’s named OsDisk. Let’s expand on it to see what it might have inside.

But, cue the sad trombone. There does not appear to be a storage URI in here. There’s just a reference to a VHD.

Screenshot that shows the contents of the OsDisk object.

However, when we access that property, we do see something useful inside.

$vm.StorageProfile.OsDisk.Vhd

Screenshot that shows results after accessing the Vhd property of the OsDisk object.

“Winner!”

But wait, we’re not done yet. Before we can use this URI, we need to drop the excess, which is the VHD file name.

I’m certain there is a really cool way to do what I did with regular expressions, but I found this nifty little trick with Select-String and Substring to pull it all together

First we grab the URI:

$VMStorageURL=($vm.StorageProfile.OsDisk.Vhd).uri

Next, we flush it though our little VHD cleaning trick:

$StorageGroupURL=$VMStorageURL.substring(0,(($VMStorageURL| Select-String -Pattern '/' -AllMatches).Matches[-1].Index)+1)

What this is actually doing is:

  1. To find all occurrences of the ‘/’ character, we need to know the position of the last one:

$VMStorageURL| Select-String -Pattern '/' -AllMatches).Matches[-1].Index

  1. Pull a Substring of everything from the beginning to wherever that last ‘/’ is:

$VMStorageURL.substring(0,(($VMStorageURL| Select-String -Pattern '/' -AllMatches).Matches[-1].Index)+1)

  1. And then, of course, store it back in the original object:

$StorageGroupURL=$VMStorageURL.substring(0,(($VMStorageURL| Select-String -Pattern '/' -AllMatches).Matches[-1].Index)+1)

Now, with that, you have the actual URI for the storage account that you’re going to need next week when you create a virtual machine.

One last visit tomorrow, and then the weekend. Here, we’ll try and tie up loose ends so that you can create a virtual machine and have no problems identifying the properties for PowerShell.

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

Until then always remember that with Great PowerShell comes Great Responsibility.

Sean Kearney
Honorary Scripting Guy
Cloud and Datacenter Management MVP

PowerTip: List all Azure Resource Manager storage accounts by using PowerShell

0
0

Summary: Use the Azure Resource Manager cmdlets to identify available storage accounts.

Hey, Scripting Guy! Question I’m working a client site, and they’d like me to document the configuration of their Azure Resource Manager environment. I’m in desperate need of a list of the storage accounts. Help me, please?

Hey, Scripting Guy! Answer One cmdlet and you’re done. Just use the Get-AzureRMStorageAccount cmdlet. If you run this, you’ll only get the list, but you can export it to a .csv file named StorageAccounts.csv. Here is an example:

Get-AzureRMStorageAccount | Export-CSV StorageAccounts.csv

The Doctor

Retrieve Azure Resource Manager virtual machine properties by using PowerShell – Part 5

0
0

Summary: Use PowerShell to retrieve Azure Resource Manager virtual machine properties.

Hey, Scripting Guy! Question There’s one thing I couldn’t figure out that I really need your help on. Just how do you find the virtual network and network security group that a virtual machines (VM) uses?

Hey, Scripting Guy! Answer Honorary Scripting Guy, Sean Kearney, is here to take away that bit of irritation. It drove me bananas, trying to figure it out.

When I look through the Azure portal, the answer seems obvious. I can clearly see what they are called.

Screenshot of the Azure portal that shows the virtual network and network security group that a VM uses.

But here, let’s get the VM that we created before.

$VM=Get-AzureRMVM –name HSG-Linux1 –ResourceGroupName HSG-AzureRG

Now, if we look at the properties by using Get-Member, you’ll see that there are two almost dead giveaways!

Screenshot that shows results of Get-Member.

“Okay, then!” That should be easy. Just access the property of one:

Screenshot that shows the properties of one network profile.

That’s what I get?

But, what you get is actually what you need. It’s actually the associated ID that you can use to run againstGet-AzureRMNetworkInterface.

But, unfortunately, you can’t just give it the string. You’ll have to get all network interfaces and filter by using Where-Object.

$NetworkInterfaceIDs=$VM.NetworkInterfaceIDs

Get-AzureRMNetworkInterface Get-AzureRmNetworkInterface | where { $_.Id -eq $vm.NetworkInterfaceIDs } | Format-Table

Screenshot that shows filtered results by using Where-Object.

What we have here is the object from that particular network card on the Azure VM. This object contains everything about that card, including the network security group and the virtual network.

Let’s store that away, and then run Get-Member against it to see what we have to work with.

$Nic=Get-AzureRMNetworkInterface Get-AzureRmNetworkInterface | where { $_.Id -eq $vm.NetworkInterfaceIDs }

$Nic | Get-Member

Screenshot that shows properties of one network card of an Azure VM.

“AHA!” You jump up. “Let me see that network security group name!”

Screenshot that shows the ID of the network security group.

The result is information that’s similar to the network interface ID. We’ll capture that for later use.

$NSGid=$NIC.NetworkSecurityGroup.ID

We can now filter on this against the Get-AzureRMNetworkSecurityGroup cmdlet.

$NSG=Get-AzureRmNetworkSecurityGroup | where { $_.ID -eq $NSGid }

Now, just where is the information about our virtual network? The challenge really isn’t in the VM. But, what we can pull up is the subnet information. The subnet is tucked away just underneath the IPConfigurations property.

$NIC.IPConfigurations

Screenshot that shows results from the IPConfigurations property.

Of course, we get that silly but powerful reference string when we pull it up.

$VNetworkSubnetID=$NIC.IpConfigurations.subnet.id

Screenshot that shows the reference string of the virtual network.

So we’ll store that away for our next task, which is to identify the virtual network. For that, we use the Get-AzureRMVirtualNetwork cmdlet. It has a few properties that are interesting but, right now, we want to look at the subnets property.

Screenshot that shows results of the Get-AzureRMVirtualNetwork cmdlet.

Within this object is a series of subnets that have been defined for a virtual network. The data is stored as that wonderful ResourceID. We can filter on it in the following manner:

$VirtualNetwork=Get-AzureRMVirtualNetwork | Where { $_.Subnets.ID –match $VnetworkSubnetID }

Congratulations! You’ve just found every single piece that you might need to recreate that VM! The other thing that you can do as well, since you now know what you’re looking for, is to mix and match.

You can now just spin up a VM in Azure with the configuration data that you want, shut it down, and grab the properties that you need for PowerShell.

How are we going to use this? That’s next week when we create VMs in Azure Resource Manager here on Hey Scripting Guys!

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

Until then, always remember that with Great PowerShell comes Great Responsibility.

Sean Kearney
Honorary Scripting Guy
Cloud and Datacenter Management MVP

 

PowerTip: List all virtual network subnets by using PowerShell

0
0

Summary: Use the Azure Resource Manager cmdlets to identify all the available subnets in a particular virtual network.

Hey, Scripting Guy! Question I’m trying to figure out a way to list all the subnet configurations in a virtual network in Azure Resource Manager. Got any tips?

Hey, Scripting Guy! Answer How about the answer? It’s a matter of combining the Get-AzureRMVirtualNetwork cmdlet and Get-AzureRMVirtualNetworkSubnetConfig. Here is an example:

Get-AzureRmVirtualNetwork -Name HSG-VirtualNetwork -ResourceGroupName HSG-AzureRG | Get-AzureRmVirtualNetworkSubnetConfig | Format-Table

The Doctor

Create Azure Resource Manager virtual machines by using PowerShell – Part 1

0
0

Summary: Use PowerShell cmdlets to start to create a virtual machine in Azure Resource Manager.

Hey, Scripting Guy! Question How do I create virtual machines (VMs) in Azure Resource Manager by using PowerShell? Where do I start?

Hey, Scripting Guy! Answer Honorary Scripting Guy, Sean Kearney, is here, and we’re going to give you some basic step-by-step guidance this week about how to spin up a VM with Azure Resource Manager PowerShell cmdlets. We’re also going to reference back to some cool tricks that we picked up last week to obtain data from a previous VM so that you don’t have to go about digging for the settings.

When I go to prepare a VM in Azure Resource Manager (outside of the actual preparation of the infrastructure such as our network or resource groups), I tend to think of six key tasks:

  • Set up the base configuration (VM size and name)
  • Set up the storage for the operating system image
  • Define the network configuration (virtual network, card, subnet, security group)
  • Set up the operating-specific details (template for the image)
  • Assign the user ID and password for the operating system
  • Spin up the VM

When I think of these six small pieces and look at them within a script, you can actually visualize the layers of the VM falling together like a well-defined structure.

The other part that makes all of this far easier in Azure Resource Manager is knowing that you can create a VM (like we did last week) within the portal and then access its properties to know what to supply to PowerShell.

As you know, often it’s not about what parameters I need to use but more about what values are valid. Because we can get valid values from other VMs within Azure Resource Manager (even if the VMs aren’t powered up), it’s far easier on the IT Pro. You can do it in the Azure portal. If you need to replicate the solution multiple times, you can take a sample PowerShell script for a VM and plug in the appropriate values.

At this point we should actually start the process, shouldn’t we? Well then, release the cmdlets!

First, as always, we need to authenticate to Azure Resource Manager by using the Add-AzureRMAccount cmdlet. To give you a quick and simple reference, here is a small sample script. It contains the subscription ID and tenant ID and prompts for the LoginID.

$SubscriptionID='00000000-0000-0000-0000-000000000000'
$TenantID='00000000-0000-0000-0000-000000000000'
$UserID='AzureLoginID@Contoso.OnMicrosoft.com'
$Credential=Get-Credential $UserID
Add-AzureRMAccount -credential $Credential -tenantid $TenantID -subscriptionid $SubscriptionID

Now that we’re authenticated, we can start to do the first big piece: start up the configuration.

The first cmdlet that we’re going to use is the New-AzureRMVMConfig cmdlet. Its task is actually quite simple: to lay down the very first piece of our VM definition.

The cmdlet will need two parameters at a minimum:

  • The VM (and by proxy, the computer name)
  • The machine size

If you have an availability set defined, which is a key piece that you need to provide redundancy in Azure, you can provide it here.

The VM size is pretty critical depending on your need and your loads. A complete description and sizing chart is at Sizes for virtual machines in Azure.

The easy answer for the size to choose is, “It depends.” The amazing answer to everything from a consultant.

Put these words in your head to determine the answer:

  • Budget
  • Availability
  • Performance

In some cases, you can have a very expensive environment that only starts up and shuts down for hours, days, or even a month. You can also have several smaller solutions that are spread across different locations. This can take some thought.

For our reference, we’re going to presume that you’re working with your last VM as a reference and are satisfied with the size.

From last week, we obtained the size of our previous VM by grabbing the VM object from Azure Resource Manager and obtaining the size property directly.

# Get Virtual Machine Object from AzureRM
$VM=Get-AzureRMVM –ResourceGroupName HSG-AzureRG –Name HSG-Linux1
# Retrieve Virtual Machine Size from Object
$VMSize=$vm.HardwareProfile.VmSize

In the case of this particular VM, I piped the results to the CLIP command to store it on the clipboard and pasted it into my CreateAzureVM.ps1 Script.

$VMSize | Clip

One CTRL-V or mouse click later…

$VMSize=’ Standard_A0’

At this point, we choose a new VM name:

$VMName=’HSG-Server1’

Then, we define the configuration by using this cmdlet:

$VMConfig=New-AzureRMVMConfig –VMName $VMName –VMSize $VMSize

This really doesn’t do anything in Azure yet. It’s just defining an object so that it won’t trap for the size or the name.

But, trapping for the name wouldn’t be difficult. You could just run something simple like this first:

$VMFound=$NULL; $VMFound=Get-AzureRMVM –name $VMName –ResourceGroupName HSG-AzureRG
If ($VMFound)
{
Write-output “Virtual Machine name $VMName Already Exists”
}
Else
{
$VMConfig=New-AzureRMVMConfig –VMName $VMName –VMSize $VMSize
}

We have now started the base. Tomorrow, we’ll continue on with defining our storage for our new VM in Azure Resource Manager.

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

Until then, always remember that with Great PowerShell comes Great Responsibility.

Sean Kearney
Honorary Scripting Guy
Cloud and Datacenter Management MVP

Viewing all 3333 articles
Browse latest View live




Latest Images