Advanced Windows PowerShell Scripting Video Training

Advanced Windows PowerShell Scripting Video Training
Advanced Windows PowerShell Scripting Video Training

Friday, September 28, 2012

Error when moving from Core to full GUI in Server 2012

If you are installing the full GUI on your Server core 2012 and receive this error, it is an easy fix.

 

Install-WindowsFeature : The request to add or remove features on the

specified server failed.

Installation of one or more roles, role services, or features failed.

The source files could not be downloaded.

 

This simply means that your installation files need to be made available to PowerShell to do this.  To correct this, insert your installation media or map a drive to the installation source on your network.  Now add he –Source parameter to your Install-WindowsFeature cmdlet pointing to Windows folder to complete the installation

Import-Module ServerManager

Imstall-WindowsFeature –IncludeAllSubfeature User-Interfaces-Infr –Source <SourcePath>

Wednesday, September 26, 2012

Determine if the Exchange Database is Mounted with PowerShell

While delivering a class at the Federal Reserve, I had the opportunity to help out with optimizing a script for use on exchange.  The script needed to check to see if the database is mounted.  The student was able to see it mounted, but could not extract the exact integer value from the data.  Below is how we did it.

Get-Counter -Counter '\MSExchange Active Manager(*)\Database Mounted' |
ForEach-Object {$_.CounterSamples} |
Select-Object -Property InstanceName, CookedValue

 


The CookedValue is what they were ultimately looking for. 0 means dismounted and 1 means mounted.

Monday, September 24, 2012

Creating a PowerShell Profile

PowerShell has (or may have) a special script that allows you to set up your PowerShell environment when it starts.  This script can run any valid PowerShell cmdlet. This means you can load up your own functions and aliases.  I  want to caution you that if you intend to make scripts that will be used by others, make sure that you do not rely on any functionality in your profile.  If you do, your script will fail when the other user runs it.

Your profile may, or may not be there.  If you have not configured it, it may not even be there yet.  To determine if your profile is present, use this PowerShell command.

Test-Path $Profile

If it comes back True, then you already have a profile.  If not, we first need to create one.  Type this in PowerShell to create your profile.

New-Item –path $profile –type file –force

    Directory: C:\Users\Jason\Documents\WindowsPowerShell


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---         8/12/2012   6:40 PM          0 Microsoft.PowerShell_profile.ps1

OK, we have a profile. To edit it, just open it in the ISE from the shell.

PowerShell_ISE $Profile

Now just add what you want PowerShell to do each time you start it up.

Friday, September 21, 2012

How to specify the number of decimal places in PowerShell Output

PowerShell does not have any number formatting built into it. For this reason, we have to use a little bit of .NET to make some changes. Let’s say you have the number 45.54321 and you only want to display the first 2 decimal places. Here is the code.

$Num = 45.54321

"{0:N2}" -f $Num

45.54

The first zero is an index number (You will see how this works in a minute.) The N tells us what type of data we are formatting. I Borrowed the below chart from this Microsoft article.

Name

Specifier

Description

Currency

C

The value is displayed as currency, using the precision specifier to indicate the number of decimal places to be displayed.

Decimal

D

The value is displayed using the number of digits in the precision specifier; if needed, leading zeroes are added to the beginning of the number.

Percentage

P

The value is multiplied by 100 and displayed as a percentage. The precision specifier indicates the number of decimal places to be displayed.

Hexadecimal

X

The value is displayed as a hexadecimal number. The precision specifier indicates the number of characters to be displayed, with leading

The number 2 tells us how many decimal places to use.

Let’s go back to that index number. Give this a try.

$Num = 45.54321, 36.75256, 65.34255

"{0:N2}","{1:N2}","{2:N2}" -f $Num

45.54 36.75 65.34

We can also format this information as currency.

$Num = 45.54321, 36.75256, 65.34255

"{0:C2}","{1:C2}","{2:C2}" -f $Num

$45.54 $36.75 $65.34

Thursday, September 20, 2012

20410 Installing and Configuring Windows Server 2012 is now available for delivery!

 

Yesterday, MCTExpert released our fall newsletter announcing our first Windows Server 2012 class that is ready for delivery.  Much effort is being placed into this next round of course development to ensure a level of quality beyond that delivered to us from Microsoft Learning.  As a training center, I invite you to take the Windows Server 2012 classes to a new level by utilizing an instructor who is seriously committed to going the extra mile.  Please contact me at Jason@MCTExpert.com to schedule this, or another other of our classes.

 

clip_image002

Wednesday, September 19, 2012

Extract mailboxes that are forwarding email outside of your domain with PowerShell

 

While instructing a PowerShell class at the Federal Reserve Bank in Philadelphia, I took an opportunity to take a real PowerShell need and incorporate it into class.  The need was to discover any user accounts that had rules in Outlook that forward emails outside of the organization.  Below is the resulting script.

 

 

# This code is intended to run on the Exchange server in the

# Exchange Management Shell.  It is also intended to be a

# module or Dot sourced into the session.

# Enable the line of code below to Import the Exchange cmdlets.

# Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010

 

<#

.SYNOPSIS

Retrieves mailboxes that have forwarding rules outside of your email system.

.DESCRIPTION

Retrieves mailboxes that have forwarding rules outside of your email system and presents you with the mailbox owner and the forwarded address .PARAMETER EmailDomain The name of your email domain.  Any forward rules that do not match this domain will be reported.

.EXAMPLE

Find-ForwardedEmails FRB.org

 

Mailbox                                                     External Address

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

Adatum.com/Marketing/Paul West

{"myaccount@somewhere.com" [SMTP:myaccount@somewhere.com]} Adatum.com/Marketing/Paul West {"Pual@yahoo.com" [SMTP:Pual@yahoo.com]} Adatum.com/Executives/Scott MacDonald {"Scott@hotmail.com" [SMTP:Scott@hotmail.com]} Adatum.com/Users/Jason A. Yoder {"Jason@Gmail.com" [SMTP:Jason@Gmail.com]}

 

.NOTES

This function is provided without support or warranty.

Always examine any PowerShell code that you download and understand it before using it.

#>

 

Function Find-ForwardedEmails

{

    Param (

        [CmdletBinding()]

        [Parameter(Mandatory=$True)][string]$EmailDomain

    )

    Try

    {

        Write-Host "Collecting Mailbox Data, please wait" -ForegroundColor Green

        $MailboxList = Get-Mailbox -ea Stop

    }

    Catch

    {

        Write-Host "Error in Mailbox" -ForegroundColor red -BackgroundColor black

 

    }

    Finally

    {

        Write-Host "Completed collecting mailbox data." -ForegroundColor Green

        Write-host "Total mailboxes processed: "($MailboxList).count

    }

 

    # Collect Rule information from the mailboxes

    Try

    {

        Write-Host "Collecting Rulw Data, please wait" -ForegroundColor Green

        $RuleList = $MailBoxList |

        Get-InboxRule -ea SilentlyContinue |

        Where-Object {$_.ForwardTo -notLike "*$EmailDomain*"}

    }

    Catch

    {

       Write-Host "Error in Rules" -ForegroundColor red -BackgroundColor black

    }

    Finally

    {

        Write-Host "Completed collecting rules data." -ForegroundColor Green

        Write-host "Total rules processed: "($RuleList).count

    }

 

    # Output the data to the pipeline.

    ForEach ($Rule in $RuleList)

    {

        $Obj = New-Object PSObject

        $Obj | Add-Member -MemberType NoteProperty -Name "Mailbox"

-Value $Rule.MailBoxOwnerID

        $Obj | Add-Member -MemberType NoteProperty -Name "External Address" -Value $Rule.ForwardTo

 

        # Send the data to the pipeline.

        Write-Output $Obj

 

    }

} # End Function: Find ForwardedEmails

 

Monday, September 17, 2012

How to Shrink a Volume in Windows 2012

This might seem a bit easy for most readers, but some of you may have noticed that the new File and Storage Manager in the Widows 2012 Server Manager is missing something.

image

Notice that there is a option to extend a volume, but none to shrink on.  Not a problem.  You can still you the Diskpart to shrink a via command line.  The Disk Manager graphical tool from Windows Server 2008 is also still available. Just press the Windows key. Type Disk and click  Settings. Now, click Create and format hard disk partitions.

image

Right click the volume that you want to shrink and click Shrink Volume

image

Enter the amount of space that you want to shrink. 

image

You may or may not get the amount that you want.  For best results, defrag the volume before attempting to shrink it.

Friday, September 14, 2012

Windows 8 network stuck as Unidentified

Here is a neat problem. I’m experimenting with correcting disjoined client computers in the domain and stumbled across this little issue. I have the client on the same network as the domain. I can ping the domain controller. I attempted to enable Windows PowerShell remoting via command line but recieved the following error:

clip_image001

Take a look at line 5 in the middle: Network connection types on this machine is set to public.

OK, no problem. I go to Network and Sharing Center to change the network type to at least Private so I can enable the remoting. Take a look at this:

clip_image002

The network profile is not clickable. I tried several techniques that I found on the internet. No luck. This was finally what fixed it.

Open PowerShell

Type Test-ComputerSecureChannel

If the response is False then type Test-ComputerSecureChannel –Repair.

If the response is now True, then reboot.

Wednesday, September 12, 2012

Add Multiple Servers to Windows 2012 Server Manager

The new Server Manager has expanded our ability to manage multiple servers at the same time.  In the 2008 Server Manager, we could connect to another server and manage it, but then we had to connect to another server to manage a different one.  In the process, we lose our connection to the other servers.

Windows 2012 allows us to manage multiple servers at the same time.  To do this, you need to tell Server Manager which servers that you want to manage. 

Open Server Manager.

Right click All Servers and click Add Servers.

image

 

Notice the three tabs on the of the Add Servers window.  We have three methods of adding domain joined servers to

image

Add servers via Active Directory

The first method is to use Active Directory. You can filter the servers/clients that are returned to you for selection based on their operating system.  By default, all operating systems from Windows XP on up will be presented to you if they match your Name(CN): pattern.

image

Provide the full, or a partial name for the servers you want to add to Server Manager. Select the servers that you want, and click the arrow button.  You will see the servers populate in the Selected pane.

image

If you made a mistake, right click the server in the Selected pane to be removed and click Remove.

image

Your servers will now appear in Server Manager.

image

 

Add servers via DNS

You can also add server by DNS. In this case, you need to know the full name of the server, or its IP address.

Click the Search icon.

Select your server and click the arrow button.

Click OK.

image

Add servers via Import

For an import to work, you need a text file that contains the DNS names or the IP addresses of the servers that you want to add to Server Manager.  One way to create that list is with PowerShell.  With PowerShell you can create a set of criteria in which to query each potential candidate to determine if that server should be added to your text file. Using PowerShell you can create much more powerful searches that with the Active Directory or DNS methods. This is just a short example of how to generate a list of servers (no clients) with a name that starts with “Indy”.

Open PowerShell on a Domain Controller or a client/server with the Active Directory module installed on it. Enter the command below and press Enter at the end of each line. Press Enter twice after entering all lines.

Get-ADComputer –Filter ‘OperatingSystem –like “*server*”’ |

Select-Object –Property Name |

Format-Table –HideTableHeaders |

OutFile “ServerNames.txt”

 

Once that text file is create go back to Server Manager.

This time select the Import tab.

Click the […] button and browse to and select your text file.

Select the servers that you want can click the arrow button.

Click OK.

image

Monday, September 10, 2012

Can a FSRM report look at another server’s hard drive?

To simulate this, We created a shared folder on a Windows 2008 R2 server that did not have FSRM installed. On another server with FSRM installed, we attempted to connect to the remote share through the UNC path. Even though the Storage Reports Task Properties allowed this, once we clicked OK, we received the following error:

\\ServerName\ShareName is an invalid local path for namespace root, please replace it with a valid local path.

We also attempted to use the hidden share at the root of the remote servers hard drive as our access point, this did not work.

We then mapped a drive the share folder. In the Storage Reports Task Properties where we specified the location to scan, the mapped drive would not show up.

I think it is safe to say that we can allow scan local drives for FSRM reports.

Friday, September 7, 2012

In DFS, are share permissions taken into account?

In our testing in class, yes they do.  We set up a standard user account with NFTS Write permissions to a folder the was Targeted in a DFS namespace. We also shared the folder through normal folder sharing methods and specified that the user had Deny share permissions.  When attempting to access the folder through the DFS namespace, we were denied access.  We then changes the share permission for the user to Read but kept the NTFS permission for the user at Write.  When accessing the folder through the DFS namespace,  we only had Read permission.

Remember that using NTFS permissions to control access is the preferred method.  NTFS is always in effect whether you are accessing the folder locally or remotely.  This also makes Role Based Administration much easier in your environments.

Wednesday, September 5, 2012

Sticky Key problem between Windows Server 2012 and LogMeIn

This week I instructed my first class using Windows Server 2012 accessed via LogMeIn and discovered a Sticky Key problem every time you press the Shift key.
image
Here is my solution to resolve this.  First off, in the Preferences of LogMeIn for the connection to the Windows Server, click General.
Change the Keyboard and mouse priority to Host side user and click Apply at the bottom.
On the Windows 2012 server, open the Control Panel – Ease of Access – Change how your keyboard works.
Uncheck Turn on Sticky Keys.
image
Click Set up Sticky Keys.
Uncheck Turn on Sticky Keys when SHIFT is pressed five times.
image
Click OK twice.

If you are using Windows Server 2012 as a Hyper-V host, you will need to redo the Easy of Use settings on each guest operating system in order to avoid the Sticky Key Problem.

Updated Information: March 20, 2013

If you continue to have problems, Uncheck Turn on Filter Keys.


Tuesday, September 4, 2012

Recover an Object from the Active Directory Recycle Bin if its Parent OU has Also Been Deleted

Here is a good scenario.  What if you want to recover an object from the AD Recycle Bin, but its parent OU has been deleted also?  Here is a blog article that I wrote a few years ago to help simplify all the PowerShell code that you would have to use.  In short, you would have to discover the parent object and restore it before you restore the object that you want.

In the image below, you can see that we are looking at the Active Directory Administrative Center. This domain has the AD Recycle Bin turned on and we have 4 objects in the Deleted Objects area.  OU1 was the parent with OU2 and its child.  OU2 had OU3 as its child.  John Doe’s user object was stored in OU3.

We will start off by right clicking John Doe and selecting Restore. The result is an error.

image

This is because the parent Object of the John Doe object do not exists in Active Directory.  They have also been deleted.  We can find the parent of john do using PowerShell

image

Well isn't this a mess?  If you look carefully at the LastKnownParent property, you can see the object that needs to be restored first, OU3.

In the AD Administrative Center, you simply need to right click the object that gave you the warning and click Locate Parent.

image

The Parent object will get the focus.

image

We could continue to do this until we reach the parent.  Once you attempt to locate the parent of OU1, the Focus on the left pane switches to the Domain, which is the parent of OU1.  Now you can restore the objects in the following order; OU1, OU2, OU3, John Doe.  Not very efficient and what if I wanted to restore just the one object and not 4?  Right click on John Doe again and notice the option to Restore To.

Now I can choose where to restore this object to.  In this case I selected Users and clicked OK.

image

Your object is now restored.

In the case of multiple objects that need to be restored, just select them and click Restore or Restore to.

image