Quantcast
Channel: Scripting Blog
Viewing all 2129 articles
Browse latest View live

PowerTip: Send Output to Clipboard with PowerShell

$
0
0

Summary: Use Windows PowerShell to easily send output to the clipboard.

Hey, Scripting Guy! Question How can I easily capture output from the Windows PowerShell console and send it to the Windows Clipboard
          so I can paste it into another program?

Hey, Scripting Guy! Answer The standard Windows utility clip.exe accepts pipeline output, for example:

Get-EventLog application -Newest 1 | clip


The Search for a Better PowerShell Console Experience

$
0
0

Summary: Microsoft Scripting Guy, Ed Wilson, talks about the search for a better Windows PowerShell console experience.

Microsoft Scripting Guy, Ed Wilson, is here. This morning I am sipping a cup of English Breakfast tea. I added bits of spearmint, peppermint, and licorice root, along with a cinnamon stick and some lemon peel, lime peel, and orange peel. It is quite refreshing and has a bit of a bite to it. I picked up some Biscotti yesterday when I made a food run, so I am trying to be careful to not get crumbs in my keyboard.

You know I love drinking tea. In particular, I love mixing and blending my own tea experience. If I was limited to a few dried out tea bags, however, I don’t think I would enjoy tea half as much. It is sort of like comparing fast-food drive-through coffee with a nice cup of coffee I make when I grind my own Kona beans and add fresh spring water to my French press. Just no comparison.

In a way, this all relates to using the Windows PowerShell console. How you might ask? Well, let me tell you…

The problem with the Windows PowerShell console

Actually, there is no problem, per se, with the Windows PowerShell console. If you grew up in the Windows world, and you spent most of your IT career pointing with mice and clicking icons, you more than likely have no problem with the Windows PowerShell console.

If your experience is limited to using Cmd.exe to run command-line utilities such as netsh, WMIC, or even netdom.exe, coming to the Windows PowerShell console will, in fact, be a big relief.

Like the person who drives through a fast-food restaurant every morning on the way to work to get a cup of coffee, what one has is what one is used to dealing with. As long as the little plastic lid stays on the paper cup, all is well with the world. But once one goes to a place where they take pride in the flavor of their coffee, and one tastes the rich flavors, smells the exotic fragrances, and savors the perfect cup of coffee, one immediately begins to seek to replicate that experience, and no longer can fast-food, drive-through coffee satisfy.

People who have had a rich and powerful console experience and come to Windows PowerShell are left impressed with the power of the Windows PowerShell cmdlets, the immediate access to the .NET Framework, and the power of the pipeline. But they are sadly unfulfilled with the overall console experience and are left wanting.

That is, until now.

PSReadLine: solution to the problem

One of the cool things introduced in Windows PowerShell 3.0 was a hook so that line editing could be improved. Before this, the experience in the Windows PowerShell console was pretty much limited to the same functionality that existed in the decades old Cmd.exe in Windows.

The cool thing is that Jason Shirk from the Windows PowerShell team used this hook and created a GitHub project called PsReadLine. If you have PSGet, the installation is as simple as typing the following:

Install-Module PSReadline

Note PSGet is a community project that provides an easy interface into GitHub. After it is installed, modules such as Install-Module, Get-PSGetModuleInfo, and Update-Module become available.

If you don’t have PSGet, you can copy the PSReadLine.zip file from GitHub. After you unblock the zip file, unzip the files and save them to your modules directory. One of the nice things about PSGet is that I can easily update a module (should a new version come available) by typing Update-ModulePSReadLine, for example.

If I use Install-Module to install the module, it updates my Windows PowerShell profile to import the PSReadLine module. If I did a manual installation, I need to add the Import-Module PSReadLine command. Because PSReadLine only works in the Windows PowerShell console, depending on which Windows PowerShell profile I edit, I may need to add a bit of logic to avoid loading it in the Windows PowerShell ISE. This is the command I use in my Windows PowerShell profile:

If($host.Name -eq 'ConsoleHost') {import-module PSReadline}

PSReadLine provides what?

After I have installed PSReadLine, what do I get? For one thing, I get color coding in the Windows PowerShell console. No longer am I limited to basic blue and white. This is shown here:

Image of command output

Another helpful feature provided by PSReadLine is real-time syntax checking. If I have an error, such as a missing quotation mark or a missing curly brace, the prompt changes from the default white to red. This visual indicator tells me that I need to pay attention to my line and look for errors prior to running the command. This indicator is shown in the following image:

Image of indicator

The really cool thing is that PSReadLine is customizable, which means I can write my own key bindings and customize many of the default settings. One of the things I like is that I can display potential parameters. I press CTRL + Spacebar. It displays all options under my line, and it brings me back to where I need to be so that I can type my command. This is shown here:

Image of command output

These reasons alone are enough for me to download and install the free PSReadLine module, but there are many more features. Here is the list from the GitHub site:

  • Syntax coloring
  • Simple syntax error notification
  • A better multiline experience (for editing and history)
  • Customizable key bindings
  • Cmd and Emacs modes (neither are fully implemented yet, but both are usable)
  • Many configuration options
  • Bash style completion (optional in Cmd mode, default in Emacs mode)
  • Bash/zsh style interactive history search (CTRL-R)
  • Emacs yank/kill ring
  • Windows PowerShell token-based "word" movement and kill
  • Undo/redo

That is all there is to downloading and to using PSReadLine. Join me tomorrow when I will talk about more cool things that I can do with PSReadLine.

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: Load PowerShell Modules and See What’s Imported

$
0
0

Summary: Learn to parse load information about modules to see what’s imported.

Hey, Scripting Guy! Question How can I analyze what is imported when a Windows PowerShell module loads?

Hey, Scripting Guy! Answer Use the –Verbose switch when importing the module, and redirect the verbose stream to a
          text file so you can use Windows PowerShell cmdlets to parse the file. In the following example,
          all modules are loaded, verbose output is redirected to a file, and Select-String is used to parse
          the file (gmo is an alias for Get-Module and ipmo is an alias for Import-Module):

gmo -l | ipmo -Verbose | 4>>c:\fso\modload.txt

$a = Get-Content C:\fso\modload.txt

$a | Select-String "importing"

$a | Select-String "alias"

A Better PowerShell Command-Line Edit

$
0
0

Summary: Microsoft Scripting Guy, Ed Wilson, talks about using PSReadLine to improve command-line editing in Windows PowerShell.

Microsoft Scripting Guy, Ed Wilson, is here. Today I thought I would try something a bit different. It is hard to show command-line editing with screenshots and tables of shortcuts. So today’s post is basically two parts. The first part includes two tables that I built, which are basically reference material for the PSReadLine command-line enhancements.

The second part is a short (less than two minutes) video. I recorded it to illustrate a simple command-line edit. My video is nothing like the way cool Scripting Cmdlet Style video, but it should prove to be somewhat helpful.

Cursor movement

One of the cool things about PSReadLine is that it adds a lot of ways to move around in the Windows PowerShell console. Learning a few keyboard shortcuts makes me a lot more productive, and it also saves my wrists and hands from a lot of extra typing and work. Here is a table that provides the cursor movement shortcuts. For the most part, they are straightforward, and they are inline with standard keyboard shortcuts used in other places.

Cursor Movement

Shortcut

Meaning

EndOfLine  

<End>  

Move the cursor to the end of the input.

BeginningOfLine  

<Home>  

Move the cursor to the start of the input.

ForwardChar  

<Right Arrow>  

Move the cursor one character to the right. This may move the cursor to the next line of multiline input.

BackwardChar  

<Left Arrow>  

Move the cursor one character to the left. This may move the cursor to the previous line of multiline input.

ForwardWord  

unbound  

Move the cursor forward to the end of the current word, or if between words, to the end of the next word. Word delimiter characters can be set with:

Set-PSReadlineOption -WordDelimiters <string of delimiter characters>

NextWord  

<Ctrl+Right Arrow>  

Move the cursor forward to the start of the next word. Word delimiter characters can be set with:

Set-PSReadlineOption -WordDelimiters <string of delimiter characters>

BackwardWord  

<Ctrl+Left Arrow>  

Move the cursor back to the start of the current word, or if between words, to the start of the previous word. Word delimiter characters can be set with:

Set-PSReadlineOption -WordDelimiters <string of delimiter characters>

ShellForwardWord  

unbound  

Like ForwardWord except word boundaries are defined by Windows PowerShell token boundaries.

ShellNextWord  

unbound  

Like NextWord except word boundaries are defined by Windows PowerShell token boundaries.

ShellBackwardWord  

unbound  

Like BackwardWord except word boundaries are defined by Windows PowerShell token boundaries.

GotoBrace  

<Ctrl+}>  

Go to the matching parenthesis curly brace or square bracket.

AddLine  

<Shift-Enter>  

The continuation prompt is displayed on the next line, and PSReadLine waits for keys to edit the current input. This is useful to enter multiline input as a single command even when a single line is complete input by itself.

 Command-line editing

One of the real strengths of PSReadLine is the enhanced command-line editing experience. Learning a few shortcuts will vastly improve the command-line editing experience. Most of the shortcuts make sense and are familiar to me.

Edit Function

Shortcut

Meaning

CancelLine

unbound

Cancel all editing to the line and leave the line of input on the screen, but return from PSReadLine without executing the input.

RevertLine

<ESC>

Revert all of the input since the last input was accepted and executed. This is equivalent to doing Undo until there is nothing left to undo.

BackwardDeleteChar

<Backspace>

Delete the character before the cursor.

DeleteChar

<Delete>

Delete the character under the cursor.

AcceptLine

<Enter>

Attempt to execute the current input. If the current input is incomplete (for example, there is a missing closing parenthesis bracket or quotation mark), the continuation prompt is displayed on the next line and PSReadLine waits for keys to edit the current input.

AcceptAndGetNext

unbound

Like AcceptLine but after the line completes, start editing the next line from history.

BackwardDeleteLine

<Ctrl+Home>

Delete the text from the start of the input to the cursor.

ForwardDeleteLine

<Ctrl+End>

Delete the text from the cursor to the end of the input.

SelectBackwardChar

<Shift+Left Arrow>

Adjust the current selection to include the previous character.

SelectForwardChar

<Shift+Right Arrow>

Adjust the current selection to include the next character.

SelectBackwardWord

<Shift+Ctrl+Left Arrow>

Adjust the current selection to include the previous word.

SelectForwardWord

unbound

Adjust the current selection to include the next word using ForwardWord.

SelectNextWord

<Shift+Ctrl+Right Arrow>

Adjust the current selection to include the next word using NextWord.

SelectShellForwardWord

unbound

Adjust the current selection to include the next word using ShellForwardWord.

SelectShellNextWord

unbound

Adjust the current selection to include the next word using ShellNextWord.

SelectShellBackwardWord

unbound

Adjust the current selection to include the previous word using ShellBackwardWord.

SelectBackwardsLine

<Shift+Home>

Adjust the current selection to include from the cursor to the start of the line.

SelectLine

<Shift+End>

Adjust the current selection to include from the cursor to the end of the line.

SelectAll

<Ctrl+A>

Select the entire line. Moves the cursor to the end of the line.

SelfInsert

<a> <b> ...

Insert the key entered.

Redo

<Ctrl+Y>

Redo an insertion or deletion that was undone by Undo.

Undo

<Ctrl+Z>

Undo a previous insertion or deletion.

I really love the command-line editing, and it makes things a whole lot faster. I just need to keep remembering the shortcuts, which is why I made the two tables above. I have them printed out on my desk so that I have easy reference. They are also in the About_PSReadLine Help topic that is part of the PSReadLine installation.

Here is the video that illustrates using PSReadLine command-line editing to speed up Tab completion in Windows PowerShell:

That is all there is to using PSReadLine on the Windows PowerShell console command line. PSReadLine week will continue tomorrow when I will talk about more cool stuff.

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

Ed Wilson, Microsoft Scripting Guy 

PowerTip: Use PowerShell to Round Numbers

$
0
0

Summary: Learn how to use Windows PowerShell to round numbers.

Hey, Scripting Guy! Question Is there an easy way to use Windows PowerShell to round numbers up or down in a computation that produces a large amount of numbers after the decimal point?

Hey, Scripting Guy! Answer Use the static Round method from the [math] class:

PS C:\> $a = 22/7

PS C:\> $a

3.14285714285714

PS C:\> [math]::Round($a)

3

PS C:\>

Better PowerShell History Management with PSReadLine

$
0
0

Summary: Microsoft Scripting Guy, Ed Wilson, talks about using PSReadLine to gain better history support in Windows PowerShell.

Microsoft Scripting Guy, Ed Wilson, is here. Someone might have said that those PowerShellers who do not learn how to use command history are doomed to retype the same commands, but I do not recall ever hearing it. In Windows PowerShell there are five *history cmdlets. Of these, I routinely use Get-History (the alias is h) and Invoke-History (alias is r). To be honest, I do not even use these all that often.

One reason, is that the history eventually gets jumbled. Although it is possible to clear the history, or even to delete individual commands from the history that do not work all that well, it often seems a bit like too much work to do all of that. In fact, by using a combination of aliases and tab expansion, it does not take me very long to create a Windows PowerShell command in the first place. So if I have to spend a couple of minutes to find a command via the history, the advantage has been lost, and it is easier to create the command anew.

This is one of the cool things about PSReadLine. It offers better, more sophisticated history support.

     Note  This is the third post in a series about PSReadLine.

Today I will talk about the improved history feature.

A short history lesson

One of the cool things about the PSReadLine module is enhanced support for working with Windows PowerShell command history. The following table shows the functions that are included in the module and the keys to which they are bound. Some of the functions are not bound to any keys, and I will talk about that in the second half of today’s post.

 

Command

Mapping

Meaning

PreviousHistory

<UpArrow>

Replace the current input with the "previous" item from PSReadLine history.

NextHistory

<DownArrow>

Replace the current input with the "next" item from PSReadLine history.

ForwardSearchHistory

<Ctrl+s>

Search forward from the current history line interactively.

ReverseSearchHistory

<Ctrl+r>

Search backward from the current history line interactively.

HistorySearchBackward

unbound

Replace the current input with the "previous" item from PSReadLine history that matches the characters between the start, the input, and the cursor.

HistorySearchForward

unbound

Replace the current input with the "next" item from PSReadLine history that matches the characters between the start, the input, and the cursor.

BeginningOfHistory

unbound

Replace the current input with the last item from PSReadLine history.

EndOfHistory

unbound

Replace the current input with the last item in PSReadLine history, which is the possibly empty input that was entered before any history commands.

 

In Windows PowerShell, if I do not have the PSReadLine module, and I want to run a command from the command history, I need to first call Get-History so I can see the history items, and then I can get the history number to run the command. This is shown here:

Image of command output

But by using the PSReadLine module, there is a search previous history function that is mapped to the Ctrl-R keystroke combination. When I use this, a reverse search prompt appears at the Windows PowerShell console command line. I type a piece of the command that I am searching for, and it picks through the history and displays matching commands on the line. This is shown here:

Image of command

If the command is what I am looking for, I simply press ENTER, and the command populates the command console line, clears the search, and runs the command.

Customizing the key mapping

In the previous table, there are several functions that are not mapped to a specific keystroke combination. If a command is unmapped, it is available to be mapped to anything I want. I think it would be useful to map the BeginningOfHistory command to Ctrl+b.

Note  Remember key mapping is case sensitive. This makes it possible to map more single stroke commands than would be available otherwise.

To do this, I use the Set-PSReadLineKeyHandler cmdlet and specify the –Key characters as Control b <^b>, and I specify the function as BeginningOfHistory.

Note  This is really easy to do. I type the key combination, and PSReadLine automatically translates Ctrl b into ^b for me. I can also use tab expansion for the function name.

The command is shown here:

Set-PSReadLineKeyHandler -Key ^B -Function BeginningOfHistory

Checking key mappings

If I want to see which key mappings and which functions are available, I use the Get-PSReadLineKeyHandler cmdlet. The command and associated output are shown here:

Image of command output

That is all there is to using PSReadLine to work with history. PSReadLine Week will continue tomorrow when I will talk about more cool stuff.

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

Ed Wilson, Microsoft Scripting Guy

PowerTip: Add Days, Hours, and Minutes to Current Time

$
0
0

Summary: Use Windows PowerShell to easily add days, hours, and minutes to the current time.

Hey, Scripting Guy! Question How can I use Windows PowerShell to add one day, two hours, and thirty minutes to the current date and time?

Hey, Scripting Guy! Answer Create a TimeSpan object that represents one day, two hours, and thirty minutes,
          then add it to the current date and time that Get-Date retrieves:

$ts = New-TimeSpan -Days 1 -Hours 2 -Minutes 30

(get-date) + $ts

Useful Shortcuts from PSReadLine PowerShell Module

$
0
0

Summary: Microsoft Scripting Guy Ed Wilson talks about useful shortcuts from the PSReadLine Windows PowerShell module.

Microsoft Scripting Guy, Ed Wilson, is here. This is PSReadLine Week. You might also be interested in reading the following posts:

One of the really cool things about the PSReadLine Windows PowerShell module is all of the cool shortcut functions that become available. Here is a table of miscellaneous functions that are available.

Function

Key binding

Meaning

Abort

unbound

Abort the current action (that is, stop interactive history search). Does not cancel input like CancelLine.

CharacterSearch

<F3>

Read a key and search forward for that character.  With an argument, search forwards for the nth occurrence of that argument.  With a negative argument, it searches backwards.

CharacterSearchBackward

<Shift+F3>

Like CharacterSearch,  but searches backwards.  With a negative argument , it searches forwards.

ClearScreen

<Ctrl+L>

Clears the screen and displays the current prompt and input at the top of the screen.

DigitArgument

unbound

Used to pass numeric arguments to functions like CharacterSearch or YankNthArg. Alt+. Toggles the argument to be negative or non-negative.  For example, to enter 80 * characters, you could type Alt+8 Alt+0 *.

CaptureScreen

unbound

Copies selected lines to the clipboard in text and .rtf formats. Use Up and Down arrow keys to the first line to select,  then use Shift+Up arrow or Shift+Down arrow to select multiple lines.  After selecting, press ENTER to copy the text. Escape/Ctrl+C/Ctrl+G will cancel so nothing is copied to the clipboard.

DisableDemoMode

unbound

Turn off demo mode.

EnableDemoMode

unbound

Turn on demo mode. Displays a window under the input line that shows which keys are typed.

InvokePrompt

unbound

Erases the current prompt and calls the prompt function to redisplay the prompt. Useful for custom key handlers that change state, such as change the current directory.

WhatIsKey

<Alt+?>

Read a key or chord and display the key binding.

ShowKeyBindings

<Ctrl+Alt+?>

Show all of the currently bound keys.

ScrollDisplayUp

<PageUp>

Scroll the display up one screen.

ScrollDisplayDown

<PageDown>

Scroll the display down one screen.

ScrollDisplayTop

unbound

Scroll the display to the top.

ScrollDisplayToCursor

unbound

Scroll the display to the cursor.

One of the key combinations that I use often is the ShowKeyBindings function, which I access via Ctrl+Alt+?.

Note  When using the previous sequence, to get a ? on the U.S. English keyboard involves the Shift +? key combination. So the actual keys typed are <Ctrl><Alt><Shift><+>.

The output is shown here:

Image of command output

When I am getting ready to do a custom PSReadLine mapping, I use the WhatIs function to see how a key is mapped. To do this, I use the <Alt + ?> key combination. I then can type the key I am thinking about mapping and see if it is mapped. When I first type <Alt + ?>,  a prompt appears. I can then type the key combination I want. The prompt is shown here:

PS C:\>

what-is-key:

The insertion point is placed back at the Windows PowerShell prompt, and it blinks expecting input. I again type <Alt +?>, and it tells me that this combination is mapped to WhatIsKey. This is shown here:

PS C:\>

Alt+?: WhatIsKey - Show the key binding for the next chord entered

PS C:\>

Demo mode

I decide to map two keys to two functions. The first is EnableDemoMode and the second is DisableDemoMode. The key bindings are shown here:

Set-PSReadlineKeyHandler -Key ^E -Function EnableDemoMode

 Set-PSReadlineKeyHandler -Key ^D -Function DisableDemoMode

Demo mode is cool, and it is not only for demonstrations. It is useful as I experiment with using PSReadLine. It is also great for teaching Windows PowerShell classes and giving presentations. Why? Well, when Demo mode is turned on, it displays every key that is typed. This includes the Ctrl and the Alt keys, but not SHIFT.

When reading the Demo mode, realize that the most recently typed command is on the left side of the screen. In the following image, I first turned on WhatIsKey by typing Alt ?. Next I typed Ctrl D to see key mapping for that key combination.

Image of command output

That is all there is to using PSReadLine customizations. PSReadLine Week will continue tomorrow when I will talk about settings.

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: Unload All Non-Microsoft Modules

$
0
0

Summary: Learn to unload all non-Microsoft Windows PowerShell modules.

Hey, Scripting Guy! Question Windows PowerShell is acting funny and I want to unload all modules that are not written by Microsoft.
          How can I easily do this?

Hey, Scripting Guy! Answer Use Get-Module to find all loaded modules, use the Where-Object cmdlet to filter for authors
          that do not match Microsoft, and then pipe the results to the Remove-Module cmdlet:

Get-Module | where Author -notmatch 'microsoft' | Remove-Module

A Better PowerShell Console with Custom PSReadLine Functions

$
0
0

Summary: Microsoft Scripting Guy, Ed Wilson, talks about a better Windows PowerShell console experience by using custom PSReadLine functions.

Microsoft Scripting Guy, Ed Wilson, is here. I was reading an interesting article the other day. The author was talking about movies and history. The author said that in reality it does not matter if a historical movie has any basis in reality at all. The reason is that we really cannot know what things were like—say a thousand years ago. We have glimpses, slivers of light, but by-and-large, a lot of what we perceive is subject to interpretation.

We do not even need to go back a thousand years ago. For example, lots of people do not really think there was a person named William Shakespeare. (Some people think he was Francis Bacon, Christopher Marlowe, or someone else.) We have a lot more evidence for the bard of Stratford-upon-Avon, than what types of horses medieval knights rode into battle.

But one thing that is not subject to interpretation is that before I found PSReadLine editing, using the Windows PowerShell console was often frustrating (with problems in command history for commands that spanned multiple lines). At times, it was even infuriating. (Remember the edit/Tab problem in Windows PowerShell 1.0 where it would erase everything to the end of the line when you pressed Tab complete? If not, you are lucky.) But now that I have PSReadLine, those days are as far gone as ambling Palfreys in A Midsummer Night’s Dream.

     Note  This is PSReadLine Week. You might also be interested in reading the following posts:

Customizing PSReadLine

One of the real cool things about PSReadLine is how customizable it is. For example, if I wanted to create a custom handler that could clear the command history in PSReadLine. It would look like the following:

Set-PSReadlineKeyHandler -Key Ctrl+w –ScriptBlock { [PSConsoleUtilities.PSConsoleReadLine]::ClearHistory() }

In fact, in the PSReadLine module location (normally in your MY Documents\WindowsPowerShell\Modules\PSReadLine folder), there is a great sample profile. It is called SamplePSReadLineProfile.ps,1 and it contains some great customizations. In can also serve as a point of departure for additional customizations.

The sample profile includes a whole bunch of new key handlers and options:

Set-PSReadLineOption -HistorySearchCursorMovesToEnd

Set-PSReadlineKeyHandler -Key UpArrow -Function HistorySearchBackward

Set-PSReadlineKeyHandler -Key DownArrow -Function HistorySearchForward

Set-PSReadlineKeyHandler -Key Alt+D -Function ShellKillWord

Set-PSReadlineKeyHandler -Key Alt+Backspace -Function ShellBackwardKillWord

Set-PSReadlineKeyHandler -Key Alt+B -Function ShellBackwardWord

Set-PSReadlineKeyHandler -Key Alt+F -Function ShellForwardWord

Set-PSReadlineKeyHandler -Key Shift+Alt+B -Function SelectShellBackwardWord

Set-PSReadlineKeyHandler -Key Shift+Alt+F -Function SelectShellForwardWord

But the way cool things are the matching quotes, parentheses, and braces. It really makes working from the command line much better. There are actually four key handlers that are way cool in the sample profile file. Here is one of them:

Set-PSReadlineKeyHandler -Key '"',"'" `

                         -BriefDescription SmartInsertQuote `

                         -LongDescription "Insert paired quotes if not already on a quote" `

                         -ScriptBlock {

    param($key, $arg)

 

    $line = $null

    $cursor = $null

    [PSConsoleUtilities.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor)

 

    if ($line[$cursor] -eq $key.KeyChar) {

        # Just move the cursor

        [PSConsoleUtilities.PSConsoleReadLine]::SetCursorPosition($cursor + 1)

    }

    else {

        # Insert matching quotes, move cursor to be in between the quotes

        [PSConsoleUtilities.PSConsoleReadLine]::Insert("$($key.KeyChar)" * 2)

        [PSConsoleUtilities.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor)

        [PSConsoleUtilities.PSConsoleReadLine]::SetCursorPosition($cursor - 1)

    }

}

Key/command mapping

Here is a table of the default Windows PSReadLine key/command mapping assignments.

Key combination

Command

Meaning

Enter

AcceptLine

Accept the input or move to the next line ...

Shift+Enter

AddLine

Move the cursor to the next line without ...

Escape

RevertLine

Equivalent to undo all edits (clears the ...)

LeftArrow

BackwardChar

Move the cursor back one character

RightArrow

ForwardChar

Move the cursor forward one character

Ctrl+LeftArrow

BackwardWord

Move the cursor to the beginning of the c...

Ctrl+RightArrow

NextWord

Move the cursor forward to the start of t...

Shift+LeftArrow

SelectBackwardChar

Adjust the current selection to include t...

Shift+RightArrow

SelectForwardChar

Adjust the current selection to include t...

Ctrl+Shift+LeftArrow

SelectBackwardWord

Adjust the current selection to include t...

Ctrl+Shift+RightArrow SelectNextWord

SelectNextWord

Adjust the current selection to include t...

UpArrow

PreviousHistory

Replace the input with the previous item ...

DownArrow

NextHistory

Replace the input with the next item in t...

Home

BeginningOfLine

Move the cursor to the beginning of the l...

End

EndOfLine

Move the cursor to the end of the line

Shift+Home

SelectBackwardsLine

Adjust the current selection to include f...

Shift+End

SelectLine

Adjust the current selection to include f...

Delete

DeleteChar

Delete the character under the cursor

Backspace

BackwardDeleteChar

Delete the character before the cursor

Ctrl+Spacebar

PossibleCompletions

Display the possible completions without ...

Tab

TabCompleteNext

Complete the input using the next complete...

Shift+Tab

TabCompletePrevious

Complete the input using the previous complete...

Ctrl+v

Paste

Paste text from the system clipboard

Ctrl+a

SelectAll

Select the entire line. Moves the cursor...

Ctrl+c

CopyOrCancelLine

Copy or cancel selected text to the clipboard...

Ctrl+C

Copy

Copy selected region to the system clipboard...

Ctrl+l

ClearScreen

Clear the screen and redraw the current l...

Ctrl+r

ReverseSearchHistory

Search history backward interactively

Ctrl+s

ForwardSearchHistory

Search history forward interactively

Ctrl+x

Cut

Delete selected region placing deleted t...

Ctrl+y

Redo

Redo an undo

Ctrl+z

Undo

Undo a previous edit

Ctrl+Backspace

BackwardKillWord

Move the text from the start of the current...

Ctrl+Delete

KillWord

Move the text from the cursor to the end...

Ctrl+End

ForwardDeleteLine

Delete text from the cursor to the end of...

Ctrl+Home

BackwardDeleteLine

Delete text from the cursor to the start...

Ctrl+]

GotoBrace

Go to matching brace

Ctrl+Alt+?

ShowKeyBindings

Show all key bindings

Alt+0

DigitArgument

Start or accumulate a numeric argument to...

Alt+1

DigitArgument

Start or accumulate a numeric argument to...

Alt+2

DigitArgument

Start or accumulate a numeric argument to...

Alt+3

DigitArgument

Start or accumulate a numeric argument to...

Alt+4

DigitArgument

Start or accumulate a numeric argument to...

Alt+5

DigitArgument

Start or accumulate a numeric argument to...

Alt+6

DigitArgument

Start or accumulate a numeric argument to...

Alt+7

DigitArgument

Start or accumulate a numeric argument to...

Alt+8

DigitArgument

Start or accumulate a numeric argument to...

Alt+9

DigitArgument

Start or accumulate a numeric argument to...

Alt+-

DigitArgument

Start or accumulate a numeric argument to...

Alt+?

WhatIsKey

Show the key binding for the next chord e...

F3

CharacterSearch

Read a character and move the cursor to t...

Shift+F3

CharacterSearchBackward

Read a character and move the cursor to t...

PageUp

ScrollDisplayUp

Scroll the display up one screen

PageDown

ScrollDisplayDown

Scroll the display down one screen

Bonus time

Probably the leading community proponent of PSReadLine is Windows PowerShell MVP, Keith Hill. He wrote a really cool blog post: PSReadLine: A Better Line Editing Experience for the PowerShell Console. In fact, this what got me hooked on this great utility. I asked him for his comments about PSReadLine. Here is what he had to say:

"I believe this already made it into my blog post, but I love the new Ctrl+A key binding that selects the entire command. Jason Shirk, the author of PSReadLine, also added a new command, CopyOrCancelLine, which makes Ctrl+c do a regular clipboard copy if there is text selected. If no text is selected, it does the normal Ctrl+c to abort. So to copy a command to the clipboard is the standard ol’ Ctrl+a then Ctrl+c.

"Jason also created a file that is part of the installation called SamplePSReadlineProfile.ps1. It shows how to set up PSReadLine as part of your profile, in additon to providing a number of custom handlers. I use the one for inserting into a here string (Ctrl+Shift+v). Let me tell you, for supporting folks on SO, that is a very handy handler. I’m always copying XML fragments or file content fragments into a here string to try to repro a problem. Here is the script for that handler:

        Set-PSReadlineKeyHandler -Key Ctrl+Shift+v `

                                                      -BriefDescription PasteAsHereString `

                                                         -LongDescription "Paste the clipboard text as a here string" `

                                                   -ScriptBlock {

            param($key, $arg)

 

              Add-Type -Assembly PresentationCore

            if ([System.Windows.Clipboard]::ContainsText())

              {

                      # Get clipboard text - remove trailing spaces, convert \r\n to \n, and remove the final \n.

                    $text = ([System.Windows.Clipboard]::GetText() -replace "\p{Zs}*`r?`n","`n").TrimEnd()

                       [PSConsoleUtilities.PSConsoleReadLine]::Insert("@'`n$text`n'@")

         }

         else

              {

                      [PSConsoleUtilities.PSConsoleReadLine]::Ding()

         }

 }

"I also use the one for inserting smart quotes, but I don’t insert smart quotes by default. I prefer to invoke that functionality explicitly by typing Ctrl+’ or Ctrl+Shift+’. Here is the script:

Set-PSReadlineKeyHandler -Chord "Ctrl+'","Ctrl+Shift+'" `

                             -BriefDescription SmartInsertQuote `

                             -Description "Insert paired quotes if not already on a quote" `

                             -ScriptBlock {

        param($key, $arg)

 

        $line = $null

        $cursor = $null

        [PSConsoleUtilities.PSConsoleReadline]::GetBufferState([ref]$line, [ref]$cursor)

 

        $keyChar = $key.KeyChar

        if ($key.Key -eq 'Oem7') {

            if ($key.Modifiers -eq 'Control') {

                $keyChar = "`'"

            }

            elseif ($key.Modifiers -eq 'Shift','Control') {

                $keyChar = '"'

            }

        }

       

        if ($line[$cursor] -eq $keyChar) {

            # Just move the cursor

            [PSConsoleUtilities.PSConsoleReadLine]::SetCursorPosition($cursor + 1)

        }

        else {

            # Insert matching quotes, move cursor to be in between the quotes

            [PSConsoleUtilities.PSConsoleReadLine]::Insert("$keyChar" * 2)

            [PSConsoleUtilities.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor)

            [PSConsoleUtilities.PSConsoleReadLine]::SetCursorPosition($cursor - 1)

        }

    }

"I use the following handler to put parens around the whole line:

Set-PSReadlineKeyHandler -Key 'Ctrl+9' `

                             -BriefDescription ParenthesizeLine `

                             -LongDescription "Put parenthesis around the entire line and move the cursor to the end of line" `

                             -ScriptBlock {

        param($key, $arg)

          $line = $null

        $cursor = $null

        [PSConsoleUtilities.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor)

        [PSConsoleUtilities.PSConsoleReadLine]::Replace(0, $line.Length, '(' + $line + ')')

        [PSConsoleUtilities.PSConsoleReadLine]::EndOfLine()

    }

"I use these last two to skip around a long command line by whole pipe stages:

Set-PSReadlineKeyHandler -Chord Ctrl+\ `

                             -BriefDescription SearchForwardPipeChar `

                             -Description "Searches forward for the next pipeline character" `

                             -ScriptBlock {

        param($key, $arg)

        [PSConsoleUtilities.PSConsoleReadLine]::CharacterSearch($key, '|')

    }

    Set-PSReadlineKeyHandler -Chord Ctrl+Shift+\ `

                             -BriefDescription SearchBackwardPipeChar `

                             -Description "Searches backward for the next pipeline character" `

                             -ScriptBlock {

        param($key, $arg)

        [PSConsoleUtilities.PSConsoleReadLine]::CharacterSearchBackward($key, '|')

    }

"This is basically using the character search feature to long forwards (or backwards) for “|" characters. PSReadLine is the bomb!"

More bonus

Jason Shirk is currently working on an update to PSReadLine. It will have a couple of cool new features. Here is Jason’s latest handy custom completion, which is inspired by marks in vim or bookmarks in an editor. You add this to your profile. When you press Ctrl+Shift+j and type one more character, that sets a bookmark to the current directory. To jump back to that directory, type Ctrl+j and the character. Notice that the prompt is updated to show the directory change.

$global:PSReadlineMarks = @{}

Set-PSReadlineKeyHandler -Key Ctrl+Shift+j `

                         -BriefDescription MarkDirectory `

                         -LongDescription "Mark the current directory" `

                         -ScriptBlock {

    param($key, $arg)

    $key = [Console]::ReadKey($true)

    $global:PSReadlineMarks[$key.KeyChar] = $pwd

}

Set-PSReadlineKeyHandler -Key Ctrl+j `

                         -BriefDescription JumpDirectory `

                         -LongDescription "Goto the marked directory" `

                         -ScriptBlock {

 

    param($key, $arg)

    $key = [Console]::ReadKey($true)

    $dir = $global:PSReadlineMarks[$key.KeyChar]

    if ($dir)

    {

        cd $dir

        [PSConsoleUtilities.PSConsoleReadLine]::InvokePrompt()

    }

}

That is all there is to customizing PSReadLine. This also concludes PSReadLine Week. Join me tomorrow when Honorary Scripting Guy and Microsoft Windows PowerShell MVP, Sean Kearney, begins a series about using Windows PowerShell with LYNC. It is some good stuff that you do not want to miss. Make plans now—it all begins tomorrow morning.

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: Determine PSReadLine Option Configuration

$
0
0

Summary: Use a cmdlet to find the way PSReadLine options are configured.

Hey, Scripting Guy! Question I recently started using PSReadLine, and I would like to see the way options are configured.
          How can I report the options settings?

Hey, Scripting Guy! Answer Use the Get-PSReadLineOption cmdlet.

Weekend Scripter: Automating the Preparation of Lync Server 2013—Part 1

$
0
0

Summary: Prep Windows Server 2012 R2 for a Lync Server 2013 installation.

Honorary Scripting Guy, Sean Kearney, is here, and today I'm doing something I've been itching to do for a while...Automate the creation of a Lync server!

You see, a while back, our Lync guy left the company. My boss looked at me and said, "You know anything about Lync?"

Ever been in one of those situations? Fortunately for me, I had spun up and managed OCS 2007 in the past, so it wasn’t completely scary.

One of our biggest challenges was disaster recovery. It appeared somewhere between "Spin up a Lync Server" and "Hand it off to infrastructure." Somebody forgot to create documentation for disaster recovery. *Oops!*

So it was in this process that I had to spin a Lync Server in a brand new configuration in the lab to see what it would take to install and manage. The nice part is it really wasn't that difficult. The cool part is there is a lot in the process that can be automated.

So our environment will be a simple one—a simple server Lync server. But the process for prepping that server is the key issue we're going to resolve. We're going to find out just how much we can automate our Lync setup.

Our environment includes two virtual machines:

  Machine 1:

  • Role: domain controller, Active Directory Certificate Services, DNS, DHCP
  • Name: Contoso-DC
  • Windows Server 2012 R2 Standard
  • 1 CPU, 1 GB Ram, 127 GB hard drive

  Machine 2:

  • Role: Lync Server 2013 Standard
  • Name: Contoso-Lync
  • Windows Server 2012 R2 Standard
  • 1 CPU, 4 GB Ram, 127 GB hard drive

We're going to presume you know how to spin up a new domain controller in Windows Server 2012 R2. If not, there are so many articles (including some in the Hey, Scripting Guys! Blog) to guide you in that aspect.

So first we plug that media into the Lync server and...Tada!

Being that this is a clean server, the first thing Lync wants to have installed is the Visual C++ 2012 x64 Minimum Runtime package:

Image of message

So of course, we'll let it do that. But if you would prefer to pre-install it yourself (which would skip by this little message), you can. This file is located under the Setup\amd64 folder within the Lync media. From this point forward, we will presume the DVD drive for Lync or mounted ISO is drive D.

You can pre-install it with this line:

D:\Setup\Amd64\VCREDIST_X64.EXE /INSTALL /PASSIVE /NORESTART

This will provide a nice little progress bar as the runtime pre-installs.                 

Normally, you would go through the clicky, clicky, "wizard-o-matic." There is nothing wrong with that. It's a well designed system with checks and balances.

Our next step would be to extend the Active Directory schema.

We have two options for this. One, we write the lines directly with ldifde with credentials as a schema admin:

ldifde -i -v -k -s EOT-DC -f externalschema.ldf -c DC=X "DC=contoso,DC=local"

ldifde -i -v -k -s EOT-DC -f serverschema.ldf -c DC=X "DC=contoso,DC=local"

ldifde -i -v -k -s EOT-DC -f backcompatschema.ldf -c DC=X "DC=contoso,DC=local"

ldifde -i -v -k -s EOT-DC -f versionschema.ldf -c DC=X "DC=contoso,DC=local"

You could even wrap this in a CMD file so you can run this only once:

Rem First Parameter is Drive letter of Lync 2013 DVD Media or mounted ISO

Rem Second Paramater is Fqdn or Netbios Name of Domain Controller of domain to Extend Schema

Rem Third Parameter is Distinguished Name of Domain IE: "DC=Contoso,DC=local"

ldifde -i -v -k -s %2 -f %1\support\schema\externalschema.ldf -c DC=X %3

ldifde -i -v -k -s %2 -f %1\support\schema\serverschema.ldf -c DC=X %3

ldifde -i -v -k -s %2 -f %1\support\schema\backcompatschema.ldf -c DC=X %3

ldifde -i -v -k -s %2 -f %1\support\schema\versionschema.ldf -c DC=X %3

Then you'd have something like this, which would work fine:

ExtendLync.CMD D: EOT-DC "DC=Contoso,DC=local"

But Lync 2013 lives in Windows PowerShell, which is for making life easier. So first, let's automate the installation of the Lync core so we can gain access to the Lync module for Windows PowerShell:

MSIEXEC.EXE /I D:\Setup\AMD64\SETUP\ocscore.msi /passive /norestart

When the core completes installing, we can launch a simple Windows PowerShell script. We can extend the schema of the forest and the domain with three simple lines:

IMPORT-MODULE Lync

ENABLE-CSADFOREST

ENABLE-CSADDOMAIN

Now there is a whole pile of features that must be pre-installed for our Windows Server 2012 R2 to run Lync. They are:

  • Windows Desktop Experience
  • Windows Identity Foundation
  • IIS with the following features:

• Static Content

• Default Document

• HTTP Errors

• ASP.NET

• .NET Extensibility

• Internet Server API (ISAPI) Extensions

• ISAPI Filters

• HTTP Logging

• Logging Tools

• Tracing

• Windows Authentication

• Request Filtering

• Static Content Compression

• Dynamic Content Compression

• IIS Management Console

• IIS Management Scripts and Tools

• Anonymous Authentication (this is installed by default when IIS is installed.)

• Client Certificate Mapping Authentication

  • .NET Framework 3.5: This is critical. If you skip this step, Lync will continually fail to install.

We could sit there, clicking away to add these features. We could waste away a Saturday doing that... 

Or we could leverage the Install-WindowFeature cmdlet from Windows Server 2012 R2 and let the computer do all the work with a simple Windows PowerShell script:

Install-WindowsFeature Windows-Identity-Foundation

Install-WindowsFeature Web-Webserver

Install-WindowsFeature Web-Default-Doc

Install-WindowsFeature Web-Static-Content

Install-WindowsFeature Web-Http-Errors

Install-WindowsFeature Web-ASP-Net

Install-WindowsFeature Web-Net-Ext

Install-WindowsFeature Web-Isapi-Ext

Install-WindowsFeature Web-Isapi-Filters

Install-WindowsFeature Web-Http-Logging

Install-WindowsFeature Web-Http-Tracing

Install-WindowsFeature Web-Log-Libraries

Install-WindowsFeature Web-Windows-Auth

Install-WindowsFeature Web-Filtering

Install-WindowsFeature Web-Stat-Compression

Install-WindowsFeature Web-Dyn-Compression

Install-WindowsFeature Web-Mgmt-Console

Install-WindowsFeature Web-Scripting-Tools

Install-WindowsFeature Web-Client-Auth

Install-WindowsFeature Desktop-Experience

You could concatenate a lot of this into one line to improve speed, but you lose on readability. For this post, I'm going for readability because the following script would be so hard on the eyes:

Install-WindowsFeature Windows-Identity-Foundation Web-Webserver Web-Default-Doc Web-Static-ontent Web-Http-Errors Web-ASP-Net Web-Net-Ext Web-Isapi-Ext Web-Isapi-Filters Web-Http-Logging Web-Http-Tracing Web-Log-Libraries Web-Windows-Auth Web-Filtering Web-Stat-Compression Web-Dyn-Compression Web-Mgmt-Console Web-Scripting-Tools Web-Client-Auth Desktop-Experience

We now have a base server almost prepped for Lync! We still need to populate our SQL Server instance and install the rest of the server, but...

It's Saturday! Time to put up our feet and rest on a job well done!

I invite you to follow the Scripting Guys on Twitter and Facebook. If you have any questions, send an email to the Scripting Guys at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then just remember, the Power of Shell is in you.

Sean Kearney, Windows PowerShell MVP and Honorary Scripting Guy

PowerTip: Extend Active Directory Schema for Lync with PowerShell

$
0
0

Summary: Learn to use the Lync module for Windows PowerShell to extend the Active Directory schema.

Hey, Scripting Guy! Question Is there an easy way to use Windows PowerShell to install a new Lync server?

Hey, Scripting Guy! Answer After you have the Lync core installed on the server (even if you haven't installed Lync itself),
          you can use the Windows PowerShell cmdlets!

To extend the forest:

Enable-CSAdForest

To extend the domain:

Enable-CSAdDomain

Weekend Scripter: Automating the Preparation of Lync Server 2013—Part 2

$
0
0

Summary: Automate the installation of SQL Server Express and complete the installation of Lync Server 2013.

Honorary Scripting Guy, Sean Kearney, is here. Today, we're getting a little nerdy by automating the rest of our Lync server...on a Sunday.

Yesterday, we finished with a Windows Server 2012 R2 box with all the features and the Visual C++ 2012 x64 Minimum Runtime package installed. We also have our schema for Active Directory extended.

Note  This is the second post in a series about Lync. Before you continue, you might enjoy reading Automating the Preparation of Lync Server 2013—Part 1.

Now we're going to dive in to the fun stuff. We'll spin up SQL Server Express in an automated mode, tuning the firewall, and more!

First, we need to get a SQL Server instance running. The software is sitting in the Lync 2013 media under the Setup\amd64 folder, and it is not difficult to run. If we let Lync run, it can do it for us.

But sometimes it's fun to figure it out for ourselves.

So normally, to install SQL Server 2012 Express, we would double-click SQLEXPR_x64.exe, and get a lovely little display like this:

Image of menu

If this is your first time installing SQL Server Express, it might appear a little daunting. Clicking on "New SQL Server stand-alone installation or add features to an existing installation"is your starting point.

But if you're curious, if you go to a CMD.EXE of the Windows PowerShell prompt and launch the application with a /?,you'll get to see the hidden keys to the chest.

SQLEXPR_x64.exe /?

Image of command output

With a little poking about, I (and some online BINGing) I found the combination of parameters to get SQL Server Express to install in the manner I wanted:

SQLEXPR_x64.EXE /ACTION=Install /QS=true /IACCEPTSQLSERVERLICENSETERMS=true /UPDATEENABLED=false /INSTANCENAME=SQLEXPRESS /FEATURES=SQL,BC

This will install a basic SQL Server Express instance with a name of SQLEXPRESS and all the basic features that are supplied in SQL Server Express.

If you'd like, you can also have Lync set up the firewall settings. But here's the cool part in Lync: read the windows! I noted that in many cases, Lync would actually display the console or the Windows PowerShell cmdlets that it was running. In this manner, you can prep the server before Lync gets to it.

If you'd like to have the firewall settings pre-enabled, here are some lines I scooped from the very log files you can use:

netsh advfirewall firewall add rule name="SQL RTC Access" dir=in action=allow program="c:\Program Files\Microsoft SQL Server\MSSQL11.RTC\MSSQL\Binn\sqlservr.exe" enable=yes profile=any

netsh advfirewall firewall add rule name="SQL Browser" dir=in action=allow protocol=UDP localport=1434

This will put in the much wanted firewall exceptions for SQL Server! (Tap, tap...how I wish SQL Server would do this for me. But of course, not every SQL Server instance needs to be network-enabled by default.)

More prep work?

In Windows Server 2012 R2, we can access the DNS records directly from Windows PowerShell. So I could actually prepare a script to populate the internal DNS server records required for Lync by using the ADD-DnsServerResourceRecord cmdlet.

Add-DnsServerResourceRecord –zone Contoso.local –Ipv4address 192.168.1.100 –name sip –A –computername EOT-DC

Add-DnsServerResourceRecord –zone Contoso.local –Ipv4address 192.168.1.100 –name meet –A –computername EOT-DC

Add-DnsServerResourceRecord –zone Contoso.local –name _sip –domainname sip.contoso.local –weight 0 –priority 0 –port 5060 –computername EOT-DC

…and of course the list goes on, but you get the idea. You could even prepopulate the records. Now if you were a really creative scripter, you could grab the topology XML file, parse its contents, and grab the names for DNS!

What's interesting to me as I poke about the folder structure, is how much of Lync is simply MSI files being called up in sequence. If you were to poke about under the hood of Setup\amd64, I'll bet...

But with the bulk of our requirements pre-installed, we can pop in our Lync media, launch our topolology creator and soon get to publishing the Lync infrastructure online!

Stop by tomorrow and we'll dig into Lync and it's Windows PowerShell cmdlets!

I invite you to follow the Scripting Guys on Twitter and Facebook. If you have any questions, send an email to the Scripting Guys at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then just remember, the Power of Shell is in you.

Sean Kearney, Windows PowerShell MVP and Honorary Scripting Guy 

PowerTip: Create an SRV Record in DNS with PowerShell

$
0
0

Summary: Use Windows PowerShell cmdlets to create a server resource record.

Hey, Scripting Guy! Question Is there was a way to script the creation of my internal server resource records for my Lync deployments?

Hey, Scripting Guy! Answer If you're running Windows Server 2012 R2 or Windows Server 2012,
          use the Add-NewDNSServerResourceRecord cmdlet (the following is a one-line command
          that is broken for the webpage):

Add-DnsServerResourceRecord –zone Contoso.local –name _sip
–domainname sip.contoso.local –weight 0 –priority 0 –port 5060 –computername Contoso-DC


Managing Lync Server 2013 with Windows PowerShell—Part 1

$
0
0

Summary: Use Windows PowerShell to enable Active Directory users for Lync.

Hey, Scripting Guy! Question Hey, Scripting Guy! We just spun up our Lync server, and I need to know a very easy way to enable groups of users. I have over 10,000 records to enable and not quite enough coffee to click the mouse button all that fast!

—LN

Hey, Scripting Guy! Answer Hello LN,

Honorary Scripting Guy, Sean Kearney, is here to show you a way to get all those users enabled without burning out the left mouse button!

If you're new to managing Lync Server 2013, your first experience probably has been your visit to the Lync Server Control Panel.

Image of menu

You found it well enough organized to click the option "Enable users for Lync Server." It brought up this ever so lovely console:

Image of menu

Enabling a user or two isn't quite so difficult. But how about enabling a whole slew of them? For that, we can turn to our good friend Windows PowerShell.

To access the Lync PowerShell cmdlets, you need only launch Lync Server Management Shell. But if you prefer, you can run the cmdlets from an ordinary Windows PowerShell console. Simply launch this line in Windows PowerShell on the Lync Server:

IMPORT-MODULE Lync

At this point, you are in the wonderful world of Windows PowerShell and Lync. Now we can create a user with this cmdlet:

ENABLE-CSADUser

With this cmdlet you can take all the values you would normally key into the GUI and drop them into a repeatable line.  For example, Mr. Dent would be enabled in the following manner:

ENABLE-CSAduser –identity 'Arthur Dent' –RegistrarPool 'eot-lync.contoso.local' –sipaddresstype FirstnameLastname –sipdomain contoso.local

With that, Mr. Dent (who remembered to bring his towel, of course) can now happily hop into Lync and chat about with…well...nobody.

He was, after all, our first user. If this is a scenario in which I am going to enable many users (or maybe 10,000 users—in which case, it would be "Many, many, many users," as they said in Policy Academy), we would do things differently.

First, the simplest action of them all would be to target an organizational unit in Active Directory. Let's pick on the HitchHiker's organizational unit today. Everybody in that organizational unit will become Lync enabled. Use the Get-AdUser cmdlet as you normally would to get the users:

GET-Aduser –filter * -searchbase 'OU=GuideToGalaxy,OU=Hitchhikers,DC=Contoso,DC=local'

We can now pipe in that list directly to the Enable CS-ADuser cmdlet…

Or can we?

It turns out that this particular cmdlet is geared towards one user at a time, and it will only accept single elements, not an array. So we'll have to split up the data with a Foreach statement like so:

GET-Aduser –filter * -searchbase 'OU=GuideToGalaxy,OU=Hitchhikers,DC=Contoso,DC=local' | Foreach { ENABLE-CSAduser –identity $_.Name –RegistrarPool 'eot-lync.contoso.local' –sipaddresstype FirstnameLastname –sipdomain contoso.local }

I found the cmdlet was actually pretty user-friendly. When I was trying to figure out the different SipAddressType values, I used Tab-Complete to scroll through the potential values. Or you can simply put in a bad value, such as Towel, and watch the lovely red error message pop up with the correct potential values listed on the screen!

Enable-CsUser : Cannot bind parameter 'SipAddressType'. Cannot convert value "towel" to type

"Microsoft.Rtc.Management.AD.Cmdlets.AddressType". Error: "Unable to match the identifier name towel to a valid

enumerator name. Specify one of the following enumerator names and try again: FirstLastName, EmailAddress,

UserPrincipalName, SAMAccountName, None"

I thought that was pretty nice!

So you can be as creative as you like with enabling users, targeting groups, or simply using a CSV file, if you like. I found that after I had initially enabled staff in Lync, I was using the one-line command to enable them in my onboarding script as I created them in Active Directory.

But we all do it a little differently.

Pop back in tomorrow as we check out even more Lync cmdlets!

I invite you to follow The Scripting Guys on Twitter and Facebook. If you have any questions, send an email to The Scripting Guys at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then remember eat your cmdlets each and every day with a dash of creativity.

Sean Kearney, Windows PowerShell MVP and Honorary Scripting Guy

PowerTip: Convert to Upper Case with PowerShell

$
0
0

Summary: Learn how to use Windows PowerShell to easily capitalize a string.

Hey, Scripting Guy! Question How can I use Window PowerShell to make all the text upper case so it is all in the
          same form prior to writing to a database?

Hey, Scripting Guy! Answer Use the ToUpper method from the String class:

"string".ToUpper()

Managing Lync Server 2013 with Windows PowerShell—Part 2

$
0
0

Summary: Use Windows PowerShell to disable Active Directory users for Lync.

Hey, Scripting Guy! Question Hey, Scripting Guy!

I was so happy yesterday! I spun up thousands of users in Lync, and it worked beautifully. But now management has come back and indicated that it should not be enabled for our temporary staff. How can I quickly disable Lync users?

—LN

Hey, Scripting Guy! Answer Hello LN,

Honorary Scripting Guy, Sean Kearney, is here with more Lync cheer and cmdlets to save the day!

Note  This is the second part in a series. You might also enjoy reading Managing Lync Server 2013 with Windows PowerShell—Part 1.

First let me explain that in Lync, you have a "disabled" Lync user and a "removed" Lync user, and they are not the same (for good reason). In one state, their access to Lync is turned off. In the other, they are physically removed from the Lync environment. This is an important distinction to remember.

If you are simply disabling a Lync user, you are stopping their ability to sign-in to Lync. It's a bit like disabling a user in Active Directory. The object is still there, but it can do anything it wants. So in some cases, you might want to disable but not remove. Maybe somebody is on vacation or perhaps this is their punishment: "No Lync for you, young man, until you eat your vegetables!"

In either case, you have two options. One is our GUI friend. Within the Lync Server Control Panel, select the user (in this case, Arthur Dent), click Edit, and then click Show Details.

Image of menu

When the user name is displayed, clear the Enabled for Lync Server check box and click Commit. You've turned off the lights on him for Lync. However, note that he is still in the list of Lync users, but not as an enabled user.

Image of menu

Image of menu

Now again, for one user, using the GUI is fine. But it appears that you need to do this operation "en-masse."

Let me think…

If only there was some kind of Powerful Shell technology out there that could do this. A way to do it with one line…

*Smack!*

Of course I know! I was I teasing (or was there a Babel fish poking my ear?)

Windows PowerShell!

We can use a cmdlet called Set-CSUser. This cmdlet allows us to adjust the various settings for a Lync user, including whether Lync access has been enabled or disabled. To disable Mr. Dent's access in Lync we simply launch this:

SET-CSUser –identity 'Arthur Dent' –enabled $FALSE

This will do the same as our little GUI friend, but much faster. If we'd like to re-enable his access, we can do this:

SET-CSUser –identity 'Arthur Dent' –enabled $TRUE

In your case, you've been asked to disable access for a whole group of staff. Let's imagine the temp workers are in a particular organizational unit in Active Directory. We can target that organizational unit like when we enabled the accounts in the first place:

GET-ADUser –filter * -searchscope 'CN=Temps,DC=Contoso,DC=local'

And like our previous cmdlet, we need break it out of an array with a Foreach:

GET-ADUser –filter * -searchscope 'CN=Temps,DC=Contoso,DC=local' | Foreach { SET-CSUser –identity $_.Name –enabled $FALSE }

The advantage to using this cmdlet is obvious. You would want to cut off their access first and then later remove their accounts. When you lose the user settings in Lync, they are gone. So if the boss changes her mind later in the day or week, and she decides those workers should in fact have access, you won't have to re-populate the information, their particular pool, or in the case of enterprise voice clients, their phone extensions!

Pop in tomorrow for more Lync and Windows PowerShell goodness, and please don't forget your towel!

I invite you to follow The Scripting Guys on Twitter and Facebook. If you have any questions, send an email to The Scripting Guys at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then remember to eat your cmdlets each and every day with a dash of creativity.

Sean Kearney, Windows PowerShell MVP and Honorary Scripting Guy 

PowerTip: Add a Federation Domain to Lync with PowerShell

$
0
0

Summary: Use the Lync cmdlets to add an additional domain to Lync for federation access.

Hey, Scripting Guy! Question I'm working with a client to set up a federation, and I am trying to easily add their list of domains.
          How can I do this with Windows PowerShell?

Hey, Scripting Guy! Answer In Lync, use the New-CSAllowedDomain cmdlet:

NEW-CSAllowedDomain –identity 'fabrikam.com'

NEW-CSAllowedDomain –identity 'contoso.ca'

Managing Lync Server 2013 with Windows PowerShell—Part 3

$
0
0

Summary: Use Windows PowerShell to remove Active Directory users for Lync.

Honorary Scripting Guy, Sean Kearney, is here.

     Note This is the third part in a series. You might also enjoy reading:

Yesterday, we learned that in Lync, you can "disable" a user or you can "remove" a user. We actually disabled the Lync user in that post, which meant that the attributes and information were still in Lync, but the user was unable to access and use Lync. This is like when you disable a user in Active Directory.

Today we're going to see how to remove that user, or many users if you need to.

Let's keep one key point in mind: Short of trying to restore from backup, this is a permanent operation. So we have a couple things to think about:

  1. Mistakes can happen, so try to have something in place to prevent them.
  2. Have some kind of easy-to-implement rollback plan (see point 1).

In the GUI interface, it's very easy to remove a user from Lync (presuming, of course, that you have all the permissions and are a member of the correct groups). First, access the Lync Server Control Panel:

Image of menu

Then simply select the users you want to remove, click Action, and click Remove from Lync Server:

Image of menu

Within a prompt or two, all of these people would be removed. For a few people, that could be OK. What about removing hundreds of dead accounts? Perhaps you want a rollback option? For this, we can step in to Windows PowerShell to customize our options. We will be leveraging a new Lync cmdlet called Disable-CSUser.

The first time I saw this cmdlet, I made the mistake of presuming that it was meant to only disable access (like we did in Part 2). Fortunately, I found out in a lab environment that this is not true. It really should have been called Remove-CSUser because you are removing the object from Lync.

If it makes it easier to remember or use, we can make up an alias like this:

NEW-Alias REMOVE-CSuser DISABLE-CSuser

Now removing an object is quite simple. We supply in the identity and…

Oh, wait a minute! Didn't I say we wanted to keep two important things in mind?

  1. Mistakes can happen, so try to have something in place to prevent them.
  2. Have some kind of easy-to-implement rollback plan (see point 1).

So to prevent mistakes from happening, or at least giving you a chance to see what is going to happen before it does, the Disable-CSUser cmdlet (like many "destructive" cmdlets, as I like to think of them) has the GREATEST feature ever created in Windows PowerShell—the -whatif parameter.

To see what would happen if I tried to remove Mr. Ford Prefect from Lync permanently without actually removing him, I can do this:

DISABLE-CSuser –identity 'Ford Prefect' –whatif

Windows PowerShell and Lync will respond with this lovely little line:

What if: Performing the operation "Disable-CsUser" on target "CN=Ford Prefect,CN=Users,DC=Contoso,DC=local"

If I had inadvertently piped in a large list of users, this cmdlet would have warned me before I had to fill out an incident report for the sudden loss of Lync access to many of the staff.

Like the other Lync cmdlets, this one cannot accept an array of information. But we can pipe information the same as before! So if want to shut down Lync access for all Active Directory accounts that are co-op students, we can first grab a list from Active Directory:

Get—Aduser –filter * -searchbase 'CN=CoopStudents,CN=Staff,DC=Contoso,DC=Local'

We can take that list and pipe it to the Disable-CSuser cmdlet, but we're going to tack on a –whatif just in case we made an error:

Get—Aduser –filter * -searchbase 'CN=CoopStudents,CN=Staff,DC=Contoso,DC=Local' | Foreach { DISABLE-CSUser –identity $_.Name –whatif }

Then if we we are satisfied with the results, we remove the -whatif,and we can remove them with the knowledge that we can perform the task in a controlled manner.

Now all is well with the world, except of course, our co-op students are madly scrambling about wondering why they can't chat with each other in Lync anymore.

Pop back in tomorrow as we check out the important second part of disabling a user—a rollback plan!

I invite you to follow The Scripting Guys on Twitter and Facebook. If you have any questions, send an email to The Scripting Guys at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then remember to eat your cmdlets each and every day with a dash of creativity.

Sean Kearney, Windows PowerShell MVP and Honorary Scripting Guy

Viewing all 2129 articles
Browse latest View live