I’ve been quiet for some days now, there is a lot going on with some interesting projects, and I’m getting back to deliver the last parts of the series during the next two weeks, after that I will be working in a cloud monitoring series with some nice features I’ve been delivered the last two weeks with some customers.
I got some feedback from a couple of you regarding how you want the next articles to be shaped, so I’m going to do them a little more graphical, if you have any suggestions please comment.
The firs step is going to be use our SCVMM server as a WSUS too, so let’s login with our SCadmin account and start the installation:
In the server manager go to “Add roles and features”:
Navigate trough the wizard to the server role page and select Windows Server Update Services:
Add the required features:
Continue with all the defaults until you reach the WSUS “Content” page, select a folder in your server to store updates:
Accept the defaults and confirm the install:
Wait a few minutes for the installation process and click close.
Now go to the WSUS console in the server manager:
Launch the post installation tasks from the upper flag in the server manager:
Right clock in your server name and select “Windows Server Update Services”:
You will get a wizard:
Navigate with the defaults trough the wizard until you are in the “Specify proxy Server”, you will need to connect to the upstream server to continue, click “Start Connecting”:
Wait for completion and click Next:
Leave the English default and click Next:
Select the classifications:
Select Synchronize Manually:
Select begin initial synchronization and finish:
Now go to SCVMM Console –> Fabric.
Right click in update servers and Add Update Server:
Use the following settings and add:
Note: If you have a remote WSUS you will need to install the WSUS console in the SCVMM servers.
In the next post I will show you how the compliance baselines for updates
In this post we will provision the storage for our cluster, a disk from our SMI-S provider for the Quorum and create the Cluster.
Assign the storage for cluster:
Now to the cluster creation:
If you get an error 25325 when creating the cluster, disable all Network Interfaces that have connectivity to the Storage server except one, so you only have one communication route.
We provisioned storage and entirely created a cluster from the SCVMM Console, stay tuned for the next post.
Hi all, thanks for being so supportive with this series, I’m really glad I can help and your support is keeping me going at a fast pace to deliver to you this series of posts.
Now let’s get to the fun technical part, we will be adding 3 hosts, two of them doesn’t even have Hyper-V installed, so we will do this from the SCVMM Console and add our storage to SCVMM
Prework:
Adding the servers:
Creating the Storage Pools. I decided to go with 2 Storage Pools 1 for SSD and another for HDD, so let’s create them in the Storage server.
We have all our storage configuration in place.
Now let’s add the storage to SCVMM:
In the next post we will build the cluster from the console too, that’s really cool right?
I’m adding an index post so it’s easier for you to browse through this series of posts.
How to create a private cloud step by step with System Center part 1: Lab Setup
How to create a private cloud step by step with System Center part 2: VMM Setup
How to create a private cloud step by step with System Center part 3: Preparing for WDS with VMM
How to create a private cloud step by step with System Center part 4: Installing WDS for SCVMM
How to create a private cloud step by step with System Center part 5: Setting up Networking
How to create a private cloud step by step with System Center part 6: Bare Metal Deployment
How to create a private cloud step by step with System Center part 7: Adding our hosts
How to create a private cloud step by step with System Center part 8: Create a cluster from the console.
Now let’s check the prerequisites for the Bare Metal Deployment:
Now that we have the prerequisites we will need a profile for our hosts:
To deploy the new host:
That’s It, in the Next post we will add all the hosts and create our cluster.
Go to the Settings tab, to have more options for our networking a quick tip is to avoid the automatic creation of logical networks when you add a host:
Now let’s create a logical Network:
Now our Port Profile:
And to finish create a logical switch:
Next post
In this fourth part of the series we will install, configure, and integrate WDS to SCVMM.
Use a copy of the template disk we created in the first post of the series and create a new VM called WDS, change the name and join it to your domain.
In server Manager go to Add roles and features:
Now let’s go back to DC01 to setup DHCP:
Now let’s go back to our WDS server and complete the setup:
Now we are ready for the integration:
Note: Remember SCVMM uses RunAs Accounts which require CredSSP to run as expected, if you have this disabled by a policy for some reason, you will not be able to use RunAs Accounts.
In the next post we will add a VHDX and deploy to our cluster nodes from baremetal.
So in the middle of making this third post I realized that my home router wasn’t able to handle and forward my PXE requests, and that’s a big problem because I’m planning in showing how to deploy our cluster entirely from SCVMM Console and I’m not planning to settle for less than that.
So I needed to adjust my strategy a little bit, the changes I made are as follows:
I have all configured with static IPs for the moment:
The plan now is to configure routing in my DC01 machine so I can share the internet connection with my other machines:
Now you should have internet access in all your servers that are pointing to this DNS.
Now we need to set up the DHCP in DC01:
In the next post we will start working with VMM.
In the second part of this series I will show you the basic installation of VMM, remember this is a test environment so you will need to separate SQL role and scale VMM to suit your needs.
Prerequisites
Installing SQL 2012 with Sp2:
Installing VMM 2012 R2
In the next part we will prepare networking for WDS.
Today I decided to start a series of post while I'm building my home lab from scratch again, in this series of post I will cover all the basic knowledge you need to set a private cloud in a lab environment.
This series assumes you have a basic understanding of Hyper-V management and Virtual Machines manual deployment, basic Active Directory and DNS.
This post series will be in Spanish and English for your convenience.
When I went out to buy my setup components I had clear that I wanted a two node cluster and another machine for some administrative VMs and to be my storage provider with iSCSI to test the management capabilities for storage in VMM 2012 R2, and because I didn't need overclocking I found a pretty sweet deal in i7 4770 for the virtualization nodes and i5 4440 for the storage pc.
I had a bunch of SATA 3 disks from the updates I've been doing to my gaming setup lately, so I decided to reuse them as follows:
2 x Cluster Node PC:
Processor:
Core i7 4770
RAM:
32 gb 1600 Mhz
Storage:
500Gb HDD
Network:
3 Nics
Core i5 4440
Storage*:
120 Gb SSD for Operating System
2x120 Gb SSD + 240 Gb SSD for fast storage pool
2x500 Gb HDD for slow storage pool
2 Nics
*Notice I'm not going to use any RAID technology, just the storage pool capabilities of Windows Server.
With this setup I'm able to deploy my private cloud with no problems and test some advanced new features of VMM 2012 R2.
For the networking part I pretty much use my standard high end home router from linksys and the cheapest CISCO switch I could find that was managed and supports VLAN tagging in case I want it to test some VLAN isolation later on.
Preparing the setup for VMM:
1. Install Windows Server 2012 R2 in the Storage PC and apply all updates.
2. Install Hyper-Role in the Storage PC.
3. Create a Directory to store your Virtual Machines and VHDX.
4. Create a blank VM Gen 2 called Template and Install Windows Server 2012 R2, this will be our template VHDX, you can also use this script to create your base VHDX.
5. If you decided to go from scratch in your template you need to apply sysprep to generalize the image and make it usable as a template:
6. Don't turn on the Template VM, go to the directory you created for your VMs and VHDX, and look for the VHDX of the VM Template you created and copy it to another subdirectory called DC and to another one called VMM, so we can have the base disks for our first two machines.
7. Create 2 new VMs one called VMM and another one called DC01, and point them to the respective virtual disk you copied to each directory in the previous step.
8. Start both machines and logon as local administrator.
9. Promote the DC01 as a domain controller and DNS Server.
10. Create a virtual switch from one of the NICs, do not allow the management operating system to communicate through this, you have another Nic for management.
11. Join the VMM Server and the Storage Server to the domain.
After this basic setup we are ready to start installing our environment, I know a lot of you use differential disks for the lab setups, that's ok but I want to make this as real as possible so you can see some more detail in the process.
Next post: Installing VMM
Today the System Center Team Blog publish an exciting post http://blogs.technet.com/b/systemcenter/archive/2014/07/01/microsoft-azure-site-recovery-your-dr-site-in-microsoft-azure.aspx
Let’s think a little bit the huge impact of this new functionality in Azure.
DRP has been historically exclusive to large enterprises with enough capital to maintain two sites in different locations to failover into the other when there’s a problem with the primary site.
Maintaining two sites is costly, even having servers or rented infrastructure in a service provider datacenter comes with a high price for an infrastructure we probably never use, and we need to maintain and renew for every hardware cycle we determine, because we don’t know when we will need it, so there must be warrantees in place and everything must be in compliance with our companies infrastructure policies.
Today that model suffer a major knockout as the usual way to have a DRP, because with Azure we now can have a site in the cloud for all our critical vm replicas, I’m not going to go deep on this matter because the Team Blog post makes a great job explaining the functionality and general requirements.
What this could mean to you?, you probably are looking for a cost effective DRP solution, well you got it, it doesn’t get better than this at this moment, you really pay for what you’re using, no more maintenance or technology refresh for a second site.
Read through the product group article and leave a comment I would love to read some opinions about it.
Last week a client ask me for help with a monitor and a rule based on the result of an SQL Query, in the past I’ve done this sometimes using a powershell script, but this time I want it to use the OleDbProbe module to accomplish my goal.
After some research it was pretty straight forward to do it so I will post the sections of the code I used and explained the management pack part by part.
First I created a simple class base on Windows Server Computer Role:
<EntityTypes> < ClassTypes> < ClassType ID="test.Monitor.Class" Accessibility="Internal" Abstract="false" Base="Windows!Microsoft.Windows.ComputerRole" Hosted="true" Singleton="false" /> </ClassTypes> < /EntityTypes> Now that we have the class I need to create a discovery for it, and because I’m just going to monitor this on one specific server I go with a WMI query for the machine name:
<Discoveries> <Discovery ID="test.Monitor.Discovery" Enabled="true" Target="Windows!Microsoft.Windows.Server.Computer" ConfirmDelivery="false" Remotable="true" Priority="Normal"> <Category>Discovery</Category> < DiscoveryTypes> < DiscoveryClass TypeID="test.Monitor.Class" /> </DiscoveryTypes> <DataSource ID="DS" TypeID="Windows!Microsoft.Windows.WmiProviderWithClassSnapshotDataMapper"> < NameSpace>root\cimv2</NameSpace> <Query>Select * from Win32_ComputerSystem where name like "XXXXXXXXXXX"</Query> <Frequency>60</Frequency> < ClassId>$MPElement[Name="test.Monitor.Class"]$</ClassId> < InstanceSettings> <Settings> <Setting> <Name>$MPElement[Name="Windows!Microsoft.Windows.Computer"]/PrincipalName$</Name> <Value>$Target/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</Value> </Setting> <Setting> <Name>$MPElement[Name="System!System.Entity"]/DisplayName$</Name> <Value>$Target/Property[Type="System!System.Entity"]/DisplayName$</Value> </Setting> </Settings> </InstanceSettings> </DataSource> </Discovery> < /Discoveries>
Now that we have a class and a way to discover it, let’s get to the fun part of this post, we need to first create a probe action that it’s going to be the one that obtains the information we need, this one is going to be based on OleDbProbe module and it will receive a value for ConnectionString and Query, I’ll do it this way because it’s easier to reuse it when you need to create multiple different monitors and rules using different queries, then we need a datasource to use our probe action, notice that we can use a runas account to avoid giving priviledges to localsystem:
<ModuleTypes> < DataSourceModuleType ID="test.Monitor.DataSource" Accessibility="Internal" RunAs="test.Monitor.DBAccessAccount" Batching="false"> <Configuration> < xsd:element minOccurs="1" name="ConnectionString" type="xsd:string" /> < xsd:element minOccurs="1" name="Query" type="xsd:string" /> < xsd:element minOccurs="1" name="IntervalSeconds" type="xsd:integer" /> < xsd:element minOccurs="0" name="SyncTime" type="xsd:string" /> </Configuration> < OverrideableParameters> < OverrideableParameter ID="IntervalSeconds" Selector="$Config/IntervalSeconds$" ParameterType="int" /> < OverrideableParameter ID="SyncTime" Selector="$Config/SyncTime$" ParameterType="string" /> </OverrideableParameters> < ModuleImplementation Isolation="Any"> <Composite> < MemberModules> < DataSource ID="Scheduler" TypeID="System!System.SimpleScheduler"> <IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds> < SyncTime>$Config/SyncTime$</SyncTime> </DataSource> < ProbeAction ID="Probe" TypeID="test.monitor.OleDb.ProbeAction"> < ConnectionString>$Config/ConnectionString$</ConnectionString> <Query>$Config/Query$</Query> </ProbeAction> </MemberModules> < Composition> <Node ID="Probe"> <Node ID="Scheduler" /> </Node> </Composition> </Composite> </ModuleImplementation> < OutputType>System!System.OleDbData</OutputType> </DataSourceModuleType> < ProbeActionModuleType ID="test.monitor.OleDb.ProbeAction" Accessibility="Public" RunAs="test.Monitor.DBAccessAccount" Batching="false" PassThrough="false"> <Configuration> < xsd:element minOccurs="1" name="ConnectionString" type="xsd:string" /> < xsd:element minOccurs="1" name="Query" type="xsd:string" /> </Configuration> <OverrideableParameters> < OverrideableParameter ID="ConnectionString" Selector="$Config/ConnectionString$" ParameterType="string" /> < OverrideableParameter ID="Query" Selector="$Config/Query$" ParameterType="string" /> </OverrideableParameters> < ModuleImplementation Isolation="Any"> <Composite> < MemberModules> < ProbeAction ID="OleDBPA" TypeID="System!System.OleDbProbe"> < ConnectionString>$Config/ConnectionString$</ConnectionString> <Query>$Config/Query$</Query> < GetValue>true</GetValue> <OneRowPerItem>false</OneRowPerItem> </ProbeAction> </MemberModules> <Composition> <Node ID="OleDBPA" /> </Composition> </Composite> </ModuleImplementation> < OutputType>System!System.OleDbData</OutputType> < InputType>System!System.BaseData</InputType> </ProbeActionModuleType> < /ModuleTypes>
So we have the base we need to get the information, now we just have to create a custom monitor type, so we can accomplish our monitoring goal, this monitor will have 3 states and will receive the Connection String and Query to execute, so every time we create a monitor we can define this two things, also we have some overridable parameters IntervalSeconds, SyncTime and Thresholds, noticed that when we use the OleDbProbe module we need to create an xpath query so we can get the value out of the oledb data that is return from our datasource, this comes in a format like this “Columns[x]/Column[y]”, where x is the row we need and y the column:
<MonitorTypes> < UnitMonitorType ID="test.Monitor.MonitorType.testdbValue" Accessibility="Internal" RunAs="test.Monitor.DBAccessAccount"> < MonitorTypeStates> < MonitorTypeState ID="UnderWarning" NoDetection="false" /> < MonitorTypeState ID="OverWarning" NoDetection="false" /> < MonitorTypeState ID="OverError" NoDetection="false" /> </MonitorTypeStates> <Configuration> < xsd:element minOccurs="1" name="IntervalSeconds" type="xsd:integer" /> < xsd:element minOccurs="1" name="Query" type="xsd:string" /> < xsd:element minOccurs="1" name="ConnectionString" type="xsd:string" /> < xsd:element minOccurs="0" name="SyncTime" type="xsd:string" /> < xsd:element minOccurs="1" name="WarningThreshold" type="xsd:integer" /> < xsd:element minOccurs="1" name="ErrorThreshold" type="xsd:integer" /> < xsd:element minOccurs="1" name="ColumnsColumn" type="xsd:string" /> </Configuration> < OverrideableParameters> < OverrideableParameter ID="IntervalSeconds" Selector="$Config/IntervalSeconds$" ParameterType="int" /> <OverrideableParameter ID="SyncTime" Selector="$Config/SyncTime$" ParameterType="string" /> < OverrideableParameter ID="WarningThreshold" Selector="$Config/WarningThreshold$" ParameterType="int" /> < OverrideableParameter ID="ErrorThreshold" Selector="$Config/ErrorThreshold$" ParameterType="int" /> </OverrideableParameters> < MonitorImplementation> < MemberModules> < DataSource ID="DataSource" TypeID="test.Monitor.DataSource"> < ConnectionString>$Config/ConnectionString$</ConnectionString> <Query>$Config/Query$</Query> <IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds> < SyncTime>$Config/SyncTime$</SyncTime> </DataSource> < ProbeAction ID="Probe" TypeID="test.monitor.OleDb.ProbeAction"> < ConnectionString>$Config/ConnectionString$</ConnectionString> <Query>$Config/Query$</Query> </ProbeAction> < ConditionDetection ID="FilterUnderWarning" TypeID="System!System.ExpressionFilter"> <Expression> < SimpleExpression> < ValueExpression> < XPathQuery Type="Integer">Columns[1]/Column[1]</XPathQuery> </ValueExpression> <Operator>Less</Operator> < ValueExpression> <Value Type="Integer">$Config/WarningThreshold$</Value> </ValueExpression> </SimpleExpression> </Expression> </ConditionDetection> < ConditionDetection ID="FilterOverWarning" TypeID="System!System.ExpressionFilter"> <Expression> <And> <Expression> < SimpleExpression> < ValueExpression> <XPathQuery Type="Integer">Columns[1]/Column[1]</XPathQuery> </ValueExpression> <Operator>GreaterEqual</Operator> < ValueExpression> <Value Type="Integer">$Config/WarningThreshold$</Value> </ValueExpression> </SimpleExpression> </Expression> <Expression> < SimpleExpression> < ValueExpression> < XPathQuery Type="Integer">Columns[1]/Column[1]</XPathQuery> </ValueExpression> <Operator>Less</Operator> <ValueExpression> <Value Type="Integer">$Config/ErrorThreshold$</Value> </ValueExpression> </SimpleExpression> </Expression> </And> </Expression> </ConditionDetection> < ConditionDetection ID="FilterOverError" TypeID="System!System.ExpressionFilter"> <Expression> <SimpleExpression> < ValueExpression> <XPathQuery Type="Integer">Columns[1]/Column[1]</XPathQuery> </ValueExpression> <Operator>GreaterEqual</Operator> < ValueExpression> <Value Type="Integer">$Config/ErrorThreshold$</Value> </ValueExpression> </SimpleExpression> </Expression> </ConditionDetection> </MemberModules> < RegularDetections> < RegularDetection MonitorTypeStateID="UnderWarning"> <Node ID="FilterUnderWarning"> <Node ID="DataSource" /> </Node> </RegularDetection> < RegularDetection MonitorTypeStateID="OverWarning"> <Node ID="FilterOverWarning"> <Node ID="DataSource" /> </Node> </RegularDetection> < RegularDetection MonitorTypeStateID="OverError"> <Node ID="FilterOverError"> <Node ID="DataSource" /> </Node> </RegularDetection> </RegularDetections> </MonitorImplementation> </UnitMonitorType> < /MonitorTypes>
Finally we will create a rule and monitor as the final step, I used a simple query to get a value from the OperationsManager DB, nothing complicated, use your own query for testing your management pack:
<Rules> <Rule ID="test.Monitor.Performance.Rule" Enabled="true" Target="test.Monitor.Class" ConfirmDelivery="true" Remotable="true" Priority="Normal" DiscardLevel="100"> <Category>PerformanceCollection</Category> <DataSources> < DataSource ID="DataSource" RunAs="test.Monitor.DBAccessAccount" TypeID="test.Monitor.DataSource"> <ConnectionString>Provider=SQLOLEDB;Server=SQLSCOM;Database=OperationsManager;Integrated Security=SSPI</ConnectionString> <Query>SELECT TOP 1 [ConsoleTaskAccessibility] FROM [OperationsManager].[dbo].[ConsoleTask]</Query> < IntervalSeconds>60</IntervalSeconds> </DataSource> </DataSources> < ConditionDetection ID="MapToPerf" RunAs="test.Monitor.DBAccessAccount" TypeID="Performance!System.Performance.DataGenericMapper"> < ObjectName>testdb</ObjectName> < CounterName>CountofErrors</CounterName> < InstanceName>testdb</InstanceName> <Value>$Data/Columns[1]/Column[1]$</Value> </ConditionDetection> < WriteActions> < WriteAction ID="WriteToDB" TypeID="SC!Microsoft.SystemCenter.CollectPerformanceData" /> < WriteAction ID="WritToDW" TypeID="MicrosoftSystemCenterDataWarehouseLibrary!Microsoft.SystemCenter.DataWarehouse.PublishPerformanceData" /> </WriteActions> </Rule> < /Rules> < Monitors> < UnitMonitor ID="test.Monitor.DBValue" Accessibility="Internal" Enabled="true" Target="test.Monitor.Class" ParentMonitorID="Health!System.Health.PerformanceState" Remotable="true" Priority="Normal" RunAs="test.Monitor.DBAccessAccount" TypeID="test.Monitor.MonitorType.testdbValue" ConfirmDelivery="true"> <Category>Custom</Category> < AlertSettings AlertMessage="test.Monitor.DBValue_AlertMessageResourceID"> < AlertOnState>Warning</AlertOnState> < AutoResolve>true</AutoResolve> < AlertPriority>Normal</AlertPriority> < AlertSeverity>Error</AlertSeverity> </AlertSettings> < OperationalStates> < OperationalState ID="UIGeneratedOpStateId621f6fa1b92d4dc2bc9b2fc34d24af84" MonitorTypeStateID="UnderWarning" HealthState="Success" /> < OperationalState ID="UIGeneratedOpStateId4b3e701018e04481bc82598d8c4a9446" MonitorTypeStateID="OverWarning" HealthState="Warning" /> < OperationalState ID="UIGeneratedOpStateId005add145c944b9d9c29a4d4cbef8636" MonitorTypeStateID="OverError" HealthState="Error" /> </OperationalStates> <Configuration> < IntervalSeconds>60</IntervalSeconds> <Query>SELECT TOP 1 [ConsoleTaskAccessibility] FROM [OperationsManager].[dbo].[ConsoleTask]</Query> < ConnectionString>Provider=SQLOLEDB;Server=SQLSCOM;Database=OperationsManager;Integrated Security=SSPI</ConnectionString> < WarningThreshold>2</WarningThreshold> < ErrorThreshold>3</ErrorThreshold> < ColumnsColumn>Valor</ColumnsColumn> </Configuration> </UnitMonitor> < /Monitors>