Monday, December 15, 2014

PowerShell + Exchange : Checkbox of Doom

Many of the Exchange Admins might already be familiar with the dreaded checkbox of doom, which causes issues with move request and Mobile devices. Post by MVP Tony Redmond here explains this in detail.

Scenario & the Problem at hand :

When a User connects to the Exchange Server using his Mobile device, then after the authentication the Exchange Trusted Subsystem creates msExchActiveSyncDevices Objects for the User. This will be evident from the below screenshot for one of the User in ADSI edit.



Now what if the Exchange Trusted Subsystem doesn't have permissions on the AD User to create those Objects , all hell is let loose. This was the case I was tackling recently and searching each User in the Directory which had this checkbox of doom unchecked manually is not feasible (am lazy).

Monday, December 01, 2014

PowerShell + Azure + Exchange : Connect Mobile devices

As already mentioned in my previous post , I now have a test Exchange 2010 Server running on Azure. Now working in Mobile Device & Email Management space, my mobile devices needed to eventually connect to my Email Infrastructure to try out few scenarios.

Initially I thought that opening the https endpoint and enabling ActiveSync (for the Mailbox User) would suffice, but I was wrong. Needed to make few changes to the SSL bindings on the IIS and trust the certificate used for the same.

Let's get to it then.

When we create a new VM on Azure it gets the Certificate for the cloud service added to the machine's personal Cert store.

Below is a screenshot showing the same :





Now as mentioned in my previous post Exchange by default will create a self signed Certificate and bind it to the CAS Server for https communication.

Monday, November 03, 2014

PowerShell : Play Music until Sleep

A while back I had blogged about using PowerShell to create a playlist of random songs in VLC player & I had a rudimentary function based on that in my profile.


001
002
003
004
005
006
function play-song
{
    param([int]$count=5, [string]$Path="D:\Songs")
    Get-ChildItem $Path -recurse -filter *.mp3| Get-Random -Count $count |
        ForEach-Object -process { Start-Process $_.Fullname -verb 'AddtoPlaylistVLC'}
}

I know the name contains an unapproved verb but I was lazy to change it.


Few days back I thought of extending above function a little bit, so that my laptop Sleeps when the songs in the playlist end (hopefully I would have slept by that time )

Saturday, November 01, 2014

PowerShell + Azure + Exchange - Connect Remotely

My recent dive into the Mobile Device & Email Management space has presented me with an opportunity to learn Exchange & Office 365.

I have built up an Azure VM running Server 2008 R2 with Exchange 2010 Server on it. It didn't made a whole lot of sense to connect to the machine using RDP and then running cmdlets on Exchange Management Shell.


Well I must admit that I tried opening a normal PSSession and importing the Exchange cmdlets in there but that didn't work as the Microsoft.Exchange endpoint configuration is hosted on IIS.

So here are the steps I followed to get the Exchange cmldets via Implicit Remoting, this is very similar to what we do with Office 365. This is a beginner post as am still wrapping my head around Exchange ;)

Open the endpoint on the cloud service to allow the HTTPS traffic to your Exchange Server. Here is how the endpoints appear for my Exchange box.



Note that the Public and Private port are both 443 which means when I try reach my cloud service on port 443 it will essentially redirect the request to my Exchange Box.

Friday, October 10, 2014

PowerShell + Azure Automation : Unleash the Automation Cmdlets

In my previous post, I blogged about using Azure Automation to deploy a Windows 10  Server Technical Preview VM in my test domain running on Azure.

But if you noticed there were lot of things that we needed to do from the Azure portal. Being an advocate of doing all things from PowerShell I gave it another shot and below is what I found (notice the colors based on what I was able to do with PowerShell)  :

1. Get the Ground work ready (few bits possible)
2. Create the Assets  (not possible at the moment)
3. Create a RunBook to deploy the VM (and add it to the domain) (PowerShell Rocks !)



PowerShell + Get the Ground work ready

As already mentioned at the moment you can't create an Azure Automation account with PowerShell, but what you can do is add a new User to Azure Active directory :)

You will have to review Software Requirements and then install the Azure AD module 

Once the module named "Msonline" is installed you can very well go ahead and create a new user.

First step is connect to the AD by supplying the credentials.

Note that the User credentials you are supplying should be sourced from Azure AD (from what I understood ). So the first user has to be created in the portal manually.



Once that is done we can use the credentials of the User like below to authenticate :
001
002
$cred = Get-Credential -UserName "Admin@dexterposh.onmicrosoft.com" -Message "The Username is not the real one ;)"
Connect-MsolService -Credential $cred

Sunday, October 05, 2014

PowerShell + Azure Automation : Deploy a Windows 10 VM (Server Tech Preview) & domain join

Recently VM running Server Technical Preview were added Azure Gallery and I thought of deploying a VM running it joined to my test domain (see my post on using PowerShell to deploy a DC on Azure ), But I wanted to do that using Azure Automation.

Azure Automation is a highly scalable workflow engine offering where we can have Runbooks (PowerShell workflows) to automate long running , error prone tasks.

I first saw this in action at one of the sessions by Ravi Sir [PowerShell MVP] at one of the PowerShell Bangalore User Group meet where he used Runbooks to demonstrate really cool stuff.

Note - Azure Automation is still in preview so you might have to sign up for it by navigating to https://account.windowsazure.com/PreviewFeatures

Divided the post into 3 steps:
1. Get the Ground work ready
2. Create the Assets
3. Create a RunBook to deploy the VM (and add it to the domain)


Get the Ground work ready


First of all create an Azure Automation account from the portal (no PowerShell cmdlet for that at the moment). Once done it should show up in the Azure portal like below :






Saturday, September 20, 2014

PowerShell + SCCM - POSH Deploy v1

I wrote an article for the coveted PowerShell Magazine on how to automate query based deployments in ConfigMgr using PowerShell.

http://www.powershellmagazine.com/2014/07/22/automating-deployments-in-configuration-manager-with-powershell/

If you go through that article you will get a background of this post.


So continuing to that, I present "POSH Deploy v1" which can be used to automate Query Based deployments with Configuration Manager (tested it on CM 2012 only). I had a similar tool built in my previous project for SCCM 2007 but that one had a lot of hard coded values, tried to remove those.

The tool earlier used Winforms and this time I kicked myself to try out WPF with PowerShell. Thanks to StackOverflow and blog posts shared around these topics by awesome community people :)

Wednesday, September 03, 2014

PowerShell + WPF + GUI : Hide (Use) background PowerShell Console

Few years back, I had started wrapping my PowerShell scripts with some sort of GUI built using Windows Forms (used Primal Forms CE mostly). Things went fine for a while but then I stumbled across awesome posts by MVP Boe Prox on using WPF with PowerShell to do the same. (check Resources section)

I had been procrastinating the idea of playing with WPF for a while but then had a great discussion with MVP Chendrayan (Chen) and got inspired to do it.

One can use Visual Studio (Express Edition - which is free) to design the UI and then consume the XAML in PowerShell script...Isn't that Cool ! See resources section for links on that.

Often when we write the Code to present a nice UI to the end user there is a PowerShell console running in the background. In this post I would like to share a trick to hide/show the background console window. This trick works with both Winforms and XAML.

Note - PowerGUI & Visual Studio Express are absolutely FREE !

For the demo of this post I have a GUIdemo.ps1 script with below contents :


001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
[xml]$xaml= @"
<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Name="HideWindow" Title="Initial Window" WindowStartupLocation = "CenterScreen"
    Width = "335" Height = "208" ShowInTaskbar = "True" Background = "lightgray">
    <Grid Height="159" Name="grid1" Width="314">
        <TextBox Height="46" HorizontalAlignment="Left" Margin="44,30,0,0" Name="textBox" VerticalAlignment="Top" Width="199" />
        <CheckBox Content="Show PS Windpw" Height="52" HorizontalAlignment="Left" Margin="34,95,0,0" Name="checkBox" VerticalAlignment="Top" Width="226" FontSize="15" />
    </Grid>
</Window>
"@

Add-Type -AssemblyName PresentationFramework
$reader=(New-Object System.Xml.XmlNodeReader $xaml)
$Window=[Windows.Markup.XamlReader]::Load( $reader )

#Tie the Controls
$CheckBox = $Window.FindName('checkBox')
$textbox = $Window.FindName('textBox')


$CheckBox.Add_Checked({$textbox.text = "Showing PS Window"Show-Console})
$CheckBox.Add_UnChecked({$textbox.text = "Hiding PS Window"Hide-Console})
$Window.ShowDialog()


Save the above contents in a file and right click on it select "Run with PowerShell".


This will open up a PowerShell console window and our simple UI , right now if you check the checkbox it writes to the textbox but later on we will be able to toggle the background PowerShell Window on and off.


One of the simplest ways to hide this window as I have shown in one of my earlier post is by using PowerGUI to wrap it as an exe 

Open the Script in PowerGUI Script Editor and then go to Tools > Compile Script




This will open up another window where you can select to not show the PowerShell console.



But this option will either permanently hide the window or show it. What if I wanted to give the end users an option to toggle the background PowerShell window on and off. You would ask what purpose would it serve ?

Well I have been using this technique for a while to see various verbose messages being generated by my backend PowerShell functions.


In addition to that we can use write-host to highlight few key things in the console (Write-Host is perfect candidate here cause we just want to show stuff on the host).

So let's add the code which will provide the functionality to toggle the background PowerShell console.

Re-used the code provided at PowerShell.cz to P/Invoke.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021

#Function Definitions
# Credits to - http://powershell.cz/2013/04/04/hide-and-show-console-window-from-gui/
Add-Type -Name Window -Namespace Console -MemberDefinition '
[DllImport("Kernel32.dll")]
public static extern IntPtr GetConsoleWindow();

[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow);
'


function Show-Console {
$consolePtr = [Console.Window]::GetConsoleWindow()
[Console.Window]::ShowWindow($consolePtr, 5)
}

function Hide-Console {
$consolePtr = [Console.Window]::GetConsoleWindow()
[Console.Window]::ShowWindow($consolePtr, 0)
}


Now time to bind the functions above to the checkbox control and use few Write-Host statements in the code to make my case.


001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
[xml]$xaml= @"
<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Name="HideWindow" Title="Initial Window" WindowStartupLocation = "CenterScreen"
    Width = "335" Height = "208" ShowInTaskbar = "True" Background = "lightgray">
    <Grid Height="159" Name="grid1" Width="314">
        <TextBox Height="46" HorizontalAlignment="Left" Margin="44,30,0,0" Name="textBox" VerticalAlignment="Top" Width="199" />
        <CheckBox Content="Show PS Windpw" Height="52" HorizontalAlignment="Left" Margin="34,95,0,0" Name="checkBox" VerticalAlignment="Top" Width="226" FontSize="15" />
    </Grid>
</Window>
"@

Add-Type -AssemblyName PresentationFramework
$reader=(New-Object System.Xml.XmlNodeReader $xaml)
$Window=[Windows.Markup.XamlReader]::Load( $reader )

Write-Host -ForegroundColor Cyan -Object "Welcome to the Hide/Show Console Demo"
Write-Host -ForegroundColor Green -Object "Demo by DexterPOSH"
#Tie the Controls
$CheckBox = $Window.FindName('checkBox')
$textbox = $Window.FindName('textBox')


#Function Definitions
# Credits to - http://powershell.cz/2013/04/04/hide-and-show-console-window-from-gui/
Add-Type -Name Window -Namespace Console -MemberDefinition '
[DllImport("Kernel32.dll")]
public static extern IntPtr GetConsoleWindow();

[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow);
'


function Show-Console {
$consolePtr = [Console.Window]::GetConsoleWindow()
[Console.Window]::ShowWindow($consolePtr, 5)
}

function Hide-Console {
$consolePtr = [Console.Window]::GetConsoleWindow()
[Console.Window]::ShowWindow($consolePtr, 0)
}

Hide-Console # hide the console at start
#Events
Write-host -ForegroundColor Red "Warning : There is an issue"
$CheckBox.Add_Checked({$textbox.text = "Showing PS Window"Show-Console})
$CheckBox.Add_UnChecked({$textbox.text = "Hiding PS Window"Hide-Console})
$Window.ShowDialog() | Out-Null


Now copy the above code in PowerGUI and wrap it as an exe. Once done open the exe . Below is an animated GIF showing it in action (at the end it's a bit blurry cause of low FPS capture in gifcam). 




Saturday, August 16, 2014

PowerShell + Azure : Deploy a DC

Recently my laptop got stolen and that gave me a push to build my lab on Azure. I tweeted this and got an awesome reply by Jim Christopher[PowerShell MVP] :



Thanks to my friend Fenil Shah who lend me his laptop to try out Azure.
Cheers to having awesome friends :)


I thought it would be better if I put my notes as a post. These are entirely for my reference ;) 

The best posts around Azure + PowerShell are by Michael Washam which can be found on his blog here.

My Action plan is to configure a ServerCore Server 2012 R2 machine running Active Directory for this post from scratch, I don't have anything right now on my azure account.

Below are the steps:


  1. Sign Up for Azure (Free Trial is available)
  2. Install Azure PowerShell Module & Configure your subscription
  3. Create a Virtual Net for your LAB
  4. Deploy the VM
  5. Connecting to VM using PSRemoting
  6. Add a new Data Disk to VM
  7. Install ADDS and a new domain.
Steps 1-3 are one time activity, next time you want to spin a VM then no need to do these.

Sign Up for Azure

Go to https://azure.microsoft.com/en-us/ to sign up for a free trial of azure.
One has to supply their Credit Card / Debit Card information for verification which will deduct $1 (this is refunded back..don't worry you misers :D ).


Note - There is a credit limit of $200 in free trail and by default your subscription won't go above this limit, so be assured. 


Install Azure PowerShell Module & Configure your Subscription

There are very good articles below which describes this step:



Following the above two articles below is what I did:

001
002
003
004
005
006
007
008
009
# Get the Settings file
Get-AzurePublishSettingsFile

#Import the file
Import-AzurePublishSettingsFile -PublishSettingsFile "C:\Temp\Visual Studio Ultimate with MSDN-7-19-2014-credentials.publishsettings"

#Remove the Settings once imported
Remove-item "C:\Temp\Visual Studio Ultimate with MSDN-7-19-2014-credentials.publishsettings"



Once you have the settings file imported, you can remove it and then you can see that the Subscription information has been imported successfully using


001
002
003

#get the Subscription details
Get-AzureSubscription

After one has imported the Subscription information , one has to select the Subscription in order to use it , below is what I did [Note - I have only one subscription so I used (Get-AzureSubscription).SubscriptionName below ] .


001
Select-AzureSubscription -SubscriptionName (Get-AzureSubscription).SubscriptionName

Now to verify that this is the Subscription my Azure cmdlets will run against run the below and it should show your default Subscription details:


001
Get-AzureSubscription -Default

At this point we need to have a storage account before proceeding further as this is where your data (VM's VHD etc ) will be stored. I am going to create a storage account with the name "dexterposhstorage" (note all lowercase letters and numbers allowed).


001
002
003
004
005
006
#create the Storage Account
New-AzureStorageAccount -Location "Southeast Asia" -StorageAccountName "dexterposhstorage" -Label "DexLAB" -Description "Storage Account for my LABs" -Verbose

#Turn off the Geo Replication...am just using it for my lab
Set-AzureStorageAccount -StorageAccountName dexterposhstorage -GeoReplicationEnabled $false -Verbose

While doing this if you get an error like below:

New-AzureStorageAccount : Specified argument was out of the range of valid values.

Then probably the name you choose for the storage account is already taken or it doesn't adhere to the naming standards (only lowercase letters and numbers).

Once you have the storage account created, set it as the current storage account to be used for your default subscription (as you can create many storage account but only use one at a time )


001
002
003
#set your storage account
Set-AzureSubscription -SubscriptionName (Get-AzureSubscription -Default).SubscriptionName -CurrentStorageAccountName "deterposhstorage"

Note - The above steps are one time activity. Once you have followed the above steps then next time you have to just load the Azure PS Module and start automation.


3. Create a Virtual Net for your LAB


In order to run a full blown LAB in Azure with my own DNS, AD etc.  I have to use Virtual Networks. Right now the easiest way to do this is using the portal as there are no cmdlet to create a new VNET, there is a Set-AzureVNetConfig which requires us to create and manipulate an XML file to create VNETs, but I was looking to do this ASAP ( there are links in resources section if you want to automate this part too).

Below is the XML which I got after adding the VNET from the portal




Below is how the VNet looks like in the Azure Management Portal:




Note that in the subnet "AD" the first usable IP address is 192.168.0.4

If you want to do this using PowerShell too (which I will eventually then refer the resources at the end).


4. Deploy VM

If you are deploying a VM for first time then you have to create an affinity group (optional) , cloud service & Storage account (mandatory).

Now let's define few PowerShell variables for Affinity Group, Cloud Service, Storage Account , DNS Server IP Address and Name of our Domain Controller.

001
002
003
004
005
006

$AffinityGroup = "DexAffinityGroup"
$cloudService = "DexCloudService"
$StorageAccount = "dexterposhstorage"
$DNSIP = '192.168.0.4' #the first usable IP address in our Subnet "AD"
$VMName = 'DexDC' #Name of the VM running our Domain Controller

Now time to create a new Affinity Group.
Also I have turned off Geo-replication as this is my test LAB (my preference).

001
002
003
004
005
006
007
008
009
010
#create a new Affinity Group for my Lab resources
New-AzureAffinityGroup -Name $AffinityGroup -Location "Southeast Asia" -Label DexLAB -Description "Affinity Group for my LAB" -Verbose


In Azure when you deploy a VM it is associated with a cloud service (which is a logical container for Azure resources). So let's create a new one 


001
002
003
#Now create a new Cloud Service
New-AzureService -ServiceName $cloudService -AffinityGroup $AffinityGroup -Label DexLAB -Description "Cloud Service for my LAB" -Verbose

The house keeping activities needed to deploy VMs is done for my Azure Subsccription. Now I need to select a Image from the gallery and use it to deploy my VMs. The cmdlet to get the images is Get-AzureImage but out of all the images am looking only for the latest Server 2012 R2 image.

I use the below to get the image stored in the variable $image (see the use of -OutVariable)



[ADMIN] PS C:\> Get-AzureVMImage | where { $_.ImageFamily -eq “Windows Server 2012 R2 Datacenter” } | Sort-Object -Descending -
Property PublishedDate | Select-Object -First 1 -OutVariable image


ImageName            : a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-R2-201407.01-en.us-127GB.vhd
OS                   : Windows
MediaLink            :
LogicalSizeInGB      : 128
AffinityGroup        :
Category             : Public
Location             : East Asia;Southeast Asia;North Europe;West Europe;Japan West;Central US;East US;East US 2;South
                       Central US;West US
Label                : Windows Server 2012 R2 Datacenter, July 2014
Description          : At the heart of the Microsoft Cloud OS vision, Windows Server 2012 R2 brings Microsoft's experience
                       delivering global-scale cloud services into your infrastructure. It offers enterprise-class
                       performance, flexibility for your applications and excellent economics for your datacenter and hybrid
                       cloud environment. This image includes Windows Server 2012 R2 Update.
Eula                 :
ImageFamily          : Windows Server 2012 R2 Datacenter
PublishedDate        : 7/21/2014 12:30:00 PM
IsPremium            : False
IconUri              : WindowsServer2012R2_45.png
SmallIconUri         : WindowsServer2012R2_45.png
PrivacyUri           :
RecommendedVMSize    :
PublisherName        : Microsoft Windows Server Group
OperationDescription : Get-AzureVMImage
OperationId          : b556cf7a-a4e8-c744-8471-f0ea0e3473ca
OperationStatus      : Succeeded



[ADMIN] PS C:\> $image.imagename
a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-R2-201407.01-en.us-127GB.vhd


While deploying VMs in Azure one has to build configurations before finally creating it, so let's build the first one to specify the VM Instance size, image name (from above) etc and store the config in a variable named $NewVM.

Note the use of Tee-Object to store the Object in Variable. Now people might wonder why not use the -OutVariable as above then a small hint , go ahead and use it and check the type of the object being returned ;)



[ADMIN] PS C:\>  New-AzureVMConfig -Name $VMName -InstanceSize Small -ImageName $image.ImageName -DiskLabel "OS" -HostCaching R
eadOnly | Tee-Object -Variable NewVM


AvailabilitySetName               :
ConfigurationSets                 : {}
DataVirtualHardDisks              : {}
Label                             : DexDC
OSVirtualHardDisk                 : Microsoft.WindowsAzure.Commands.ServiceManagement.Model.PersistentVMModel.OSVirtualHardDis
                                    k
RoleName                          : DexDC
RoleSize                          : Small
RoleType                          : PersistentVMRole
WinRMCertificate                  :
X509Certificates                  :
NoExportPrivateKey                : False
NoRDPEndpoint                     : False
NoSSHEndpoint                     : False
DefaultWinRmCertificateThumbprint :
ProvisionGuestAgent               : True
ResourceExtensionReferences       :
DataVirtualHardDisksToBeDeleted   :

Time to add another config to our VM which will specify the Admin User Name and Password for the VM:
001
002
$password = "P@ssw0rd321"
$username = "DexterPOSH"


[ADMIN] PS C:\> Add-AzureProvisioningConfig -Windows -Password $password -AdminUsername $username -DisableAutomaticUpdates -VM
$newVM


AvailabilitySetName               :
ConfigurationSets                 : {DexDC, Microsoft.WindowsAzure.Commands.ServiceManagement.Model.PersistentVMModel.NetworkC
                                    onfigurationSet}
DataVirtualHardDisks              : {}
Label                             : DexDC
OSVirtualHardDisk                 : Microsoft.WindowsAzure.Commands.ServiceManagement.Model.PersistentVMModel.OSVirtualHardDis
                                    k
RoleName                          : DexDC
RoleSize                          : Small
RoleType                          : PersistentVMRole
WinRMCertificate                  :
X509Certificates                  : {}
NoExportPrivateKey                : False
NoRDPEndpoint                     : False
NoSSHEndpoint                     : False
DefaultWinRmCertificateThumbprint :
ProvisionGuestAgent               : True
ResourceExtensionReferences       : {BGInfo}
DataVirtualHardDisksToBeDeleted   :

The first VM deployed in our LAB will be a Domain Controller and we need to make sure that it gets the same local IP Address, that's why we created a Subnet named "AD" in our Virtual Network and we will place our VM there (only machine in that subnet, ensuring that it gets the first usable IPaddress there).
In addition to this as an extra precaution , we can use the cmdlet Set-AzureStaticVNetIP to bind the IP address to our VM.


001
002
003
004
005
# set the AD Subnet for this machine
 Set-AzureSubnet -SubnetNames AD -VM $newVM

 #set the Static VNET IPAddress of 192.168.0.4 for our VM
 Set-AzureStaticVNetIP -IPAddress $DNSIP -VM $newVM


After all the configurations being created, we will finally create the new VM


001
New-AzureVM -ServiceName $cloudService -VMs $newVM -VNetName "DexVNET"  -AffinityGroup DexAffinityGroup

As an alternative one can use the New-AzureQuickVM (use this if you are using Azure Automation feature). There are few cases where New-AzureVM fails miserably.

Note - In addition one can specify the -WaitForBoot (New-AzureVM) to pause the Script execution until the VM is up and ready.



Connecting to Azure VM using PSRemoting


Once the VM is up and running it is time to add a new disk to it for storing the SysVol folder for the AD Domain Services. I wanted to do this using PowerShell too as the Server 2012 supports disk management tasks. But for this I need to configure my laptop to be able to talk to the WinRM endpoint sitting behind the cloud service (by default RDP and WinRM endpoints for each of the VMs are opened).

Again this has already been explained at the below link:

http://michaelwasham.com/windows-azure-powershell-reference-guide/introduction-remote-powershell-with-windows-azure/


Following the above link, below code does the work for me:
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
$WinRMCert = (Get-AzureVM -ServiceName $CloudService -Name $VMName | select -ExpandProperty vm).DefaultWinRMCertificateThumbprint
$AzureX509cert = Get-AzureCertificate -ServiceName $CloudService -Thumbprint $WinRMCert -ThumbprintAlgorithm sha1

$certTempFile = [IO.Path]::GetTempFileName()
$AzureX509cert.Data | Out-File $certTempFile

# Target The Cert That Needs To Be Imported
$CertToImport = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $certTempFile

$store = New-Object System.Security.Cryptography.X509Certificates.X509Store "Root", "LocalMachine"
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
$store.Add($CertToImport)
$store.Close()

Remove-Item $certTempFile

After this I can remote in to my VM running up on Azure and perform all the tasks I want to, isn't it amazing ;)

Using the cmdlet Get-AzureWinRMUri, we get the connection URI.




001
002
003
#Now I can use the Get-AzureWinrmUri
    $WinRMURi = (Get-AzureWinRMUri -ServiceName $cloudService -Name $VMName).AbsoluteUri


also create credential object to be passed on when opening a PSSession.


001
002
003
004
005
006
007
008
#Convert our plain text password to secure string
$passwordsec = ConvertTo-SecureString -String $password -AsPlainText -Force
#create the Creds Object
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username,$passwordsec

#Open up a new PSSession to the Azure VM
$Session = New-PSSession -ConnectionUri $WinRMURi -Credential $cred

Hopefully if we did everything right we will have a PSSession open.


Add a new data disk to VM

Let's add the data disk now.

001
002
003
#add new data disk to store the NTDS and SysVol folders
Add-AzureDataDisk -CreateNew -DiskSizeInGB 20 -DiskLabel "NTDS" -LUN 0 -VM $DexDC  | Update-AzureVM

Please note that at the end we need to pipe the output of Add-AzureDataDisk to Update-AzureVM.

Now if you would have connected using RDP and opened the diskmgmt.msc then you could have added the new disk (GUI way).

But we are going to use PowerShell for that as the server we choose is Server 2012 R2 (which has the disk mgmt cmdlets shipped with it).


Below is the code, which will initialize , partition and format our new disk:
001
002
003
004
005
006
007
008
009
010
011

Invoke-Command -Session $session -ScriptBlock {
    Get-Disk |
    where partitionstyle -eq 'raw' |
    Initialize-Disk -PartitionStyle MBR -PassThru |
    New-Partition -AssignDriveLetter -UseMaximumSize |
    Format-Volume -FileSystem NTFS -NewFileSystemLabel "NTDS" -Confirm:$false

                          
}

You can verify the result by running the Get-Disk cmdlet in the remote PSSession.


Install ADDS and a new domain

Perfect now we have everything to promote this Azure VM as the first domain controller for our new forest.

We will put the NDTS & SysVol folder in our new data disk we added.


001
002
003
004
005
006
007
008
009
010
011

Invoke-Command -Session $Session -ArgumentList @($password-ScriptBlock {
        Param ($password)
        # Set AD install paths
        $drive = get-volume | where { $_.FileSystemLabel -eq “NTDS” }
        $NTDSpath = $drive.driveletter + ":\Windows\NTDS"
        $SYSVOLpath = $drive.driveletter + ":\Windows\SYSVOL"
        write-host "Installing the first DC in the domain"
        Install-WindowsFeature –Name AD-Domain-Services -includemanagementtools
        Install-ADDSForest -DatabasePath $NTDSpath -LogPath $NTDSpath -SysvolPath $SYSVOLpath -DomainName "dex.com" -InstallDns -Force -Confirm:$false -SafeModeAdministratorPassword $password
    }

Reboot your VM and you have your test domain up and ready in the cloud (for me it is dex.com).

One more thing once all is done, I switched my Domain Controller to the ServerCore ;)

Below is the snippet which does it for me.




001
002
003
#Convert to Server Core
Invoke-Command -Session $Session -script { Uninstall-WindowsFeature Server-Gui-Mgmt-Infra,Server-Gui-Shell -Restart}



That's it for today, probably one more post will follow which will focus on doing this entire setup using the Azure Automation (workflows).

I will be showing this at Microsoft Community Day on 23rd August, let's see if I can get that recorded.

[UPDATE] You can find the Script Snippet in entirety at below link:
https://gist.github.com/DexterPOSH/ae7ddcc6fa6aafacebc4

Resources:

http://michaelwasham.com

http://blogs.technet.com/b/keithmayer/archive/2014/08/15/scripts-to-tools-auto-provisioning-azure-virtual-networks-with-powershell-and-xml.aspx

http://blogs.blackmarble.co.uk/blogs/rhepworth/post/2014/03/03/Creating-Azure-Virtual-Networks-using-Powershell-and-XML.aspx

http://blogs.technet.com/b/kevinremde/archive/2013/01/19/create-a-windows-azure-network-using-powershell-31-days-of-servers-in-the-cloud-part-19-of-31.aspx


http://blogs.technet.com/b/keithmayer/archive/2014/04/04/step-by-step-getting-started-with-windows-azure-automation.aspx




Friday, August 15, 2014

upcoming speaking engagements

Recently started working at AirWatch by VMWare and been busy learning the new Mobile technologies. 

Not been able to do much on the PowerShell and ConfigMgr side but I did few things in Azure with PowerShell (did build my LAB up there).

So will be speaking on this very topic at the Microsoft Community Day event on 23rd August . Below is the eventbrite link to register



Later in September will be speaking at the Microsoft Event on "Transforming the Datacenter" at Bangalore, India. Below is the link for that (limited seats):

https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032592541&culture=en-IN


Also planning a few hangouts for the PowerShell Bangalore User Group to help new people embrace the Shell. :)


Monday, July 28, 2014

PowerShell (Bangalore | Hyderabad ) UG - First Hangout

Recently we have started with the hangouts covering the basics of PowerShell.

The first hangout was aired successfully on 25th August 2014 and is now available on the "PowerShell Bangalore User Group" YouTube channel, 

We talked a little bit on the background of Windows PowerShell and how it makes an ITPro's life awesome and why is it very important to get started with PowerShell.


The video can be found below:




We learned a few lessons on the feedback from community on how to improve these in future.

So hopefully we will improve in future :)
 

Cheers !