We are migrating to Windows 2008 R2 Standard and will be using a Microsoft Clustering (active-passive) configuration. Our application is heavily dependent on MSMQ private queues and our install creates well over 100 private queues using the following C# code.
MessageQueue.Create(".\private$\myqueue", false);
Since the install is not running inside the context of the cluster, the queues are created on the local node and not in the cluster.
We then tried changing the code to:
MessageQueue.Create("MYCLUSTERNAME\private$\myqueue", false);
However, you can't create private queues on a different server (in this case the cluster server context) and you receive the error "Invalid queue path name".
My two questions are:
1) Is there a way I can run the install in the cluster's context so that when creating a private queue, it would actually be creating the queue in the cluster?
2) If not, what's the best approach on creating queues in the cluster via .NET? I've read some blogs where people create a middle-man Windows service that resides inside the cluster and then their install uses interprocess communication to tell the service which queues to create. That seems like a hack, but is doable if that turns out to be the only approach.
Here is how to do it manually on the clustered instance. (Not via code)
ON THE ACTIVE NODE ONLY, Create the necessary MSMQ Queues.
a. Click Start, right click on Command prompt and click Run as administrator.
b. In the command prompt enter the following commands (Where {virtualname} is the name of the instance.)
i. SET _CLUSTER_NETWORK_HOSTNAME_={virtualname}
ii. SET _CLUSTER_NETWORK_NAME_={virtualname}
iii. Compmgmt.msc
c. Now that computer management has been started from the same command prompt as the variables, it will look like you are making changes locally, but you are actually changing them in the clustered instance.
d. Expand Services and Applications.
e. Expand Message Queuing.
f. Right Click on Private Queues and click New, Private Queue.
g. Verify that the Create in: is the virtual name.
h. In the Queue name: private$\ field put in the queue name and click the OK button.
i. Close Computer Management.
This worked on Windows 2008 R2
Same solution From Powershell (what you aren't using it yet???)
I was working on this problem for a while, found this thread recently.
http://winterdom.com/2011/10/using-powershell-with-clustered-msmq
Here's a sample script which I've been using recently that will create the private queues and set permission on it. Creates on remote machines. I work with Win2k3 servers.
Invoke-Command -ScriptBlock {
$env:_CLUSTER_NETWORK_NAME_ = 'myclusterMSMQ'
Write-Host "... load the .NET Messaging assembly"
[Reflection.Assembly]::LoadWithPartialName("System.Messaging")
$environment="perf2"
$groups=#{`
"MessageRouters"="DomainName\Group";`
"CalcDaemons"="DomainName\GroupB";`
"MessageSenders"="DomainName\GroupC";`
}
function new-queue ([string] $queuepath,[bool] $transactional)
{
if (([System.Messaging.MessageQueue]::Exists($queuepath))){throw "$queuepath already exists"}
Write-Host "creating $queuepath"
[System.Messaging.MessageQueue]::Create($queuepath,$transactional)
}
function set-msmqpermission ([string] $queuepath,[string] $account, [string] $accessright)
{
if (!([System.Messaging.MessageQueue]::Exists($queuepath))){
throw "$queuepath could not be found."
}
$q=New-Object System.Messaging.MessageQueue($queuepath)
$q.SetPermissions($account,[System.Messaging.MessageQueueAccessRights]::$accessright,
[System.Messaging.AccessControlEntryType]::Set)
}
#example usage
new-queue ".\private$\$($environment)ack" $false
set-msmqpermission ".\private$\$($environment)ack" $groups.messagerouters "FullControl"
} -ComputerName "servername (or array)"
To solve your problem try setting two environment variables before running the application:
SET _CLUSTER_NETWORK_HOSTNAME_=cluster_name
SET _CLUSTER_NETWORK_NAME_=cluster_name
It worked on Windows Server 2003 R2.
For the sake of the poor souls (like me) who have spent hours scouring how to achieve this using the .NET MessageQueue, it is possible to create queues on a clustered MSMQ without Powershell:
Environment.SetEnvironmentVariable("_CLUSTER_NETWORK_HOSTNAME_", "yourclustername", EnvironmentVariableTarget.User);
Environment.SetEnvironmentVariable("_CLUSTER_NETWORK_NAME_", "yourclustername", EnvironmentVariableTarget.User);
var path = #"yourclustername\Private$\yourprivatequeuepath";
MessageQueue.Create(path, false);
Tested on server 2012.
WARNING: Take care setting environment variables as they can be hard to clear afterwards EVEN if you set them using EnvironmentVariableTarget.User. Also, it appears that it is only necessary to set the environment variables if you're trying to access a private queue in a cluster from a machine within the cluster.
If you've accidentally set the environment variables, you can clear them in the registry at HKCU\Environment. One problem that can occur is if you've run code under a different user context that has set environment variables. In one case, I was able to log in as that user and then remove them from the registry but in another case I was debugging a website under IIS and the LOCALSYSTEM account had them set. To clear them, I published a website that set the values to null. You also want to check what the env variable values are for .User, .Process and .Machine. Note that .Process-scoped changes don't take effect until the machine is restarted if the process in question is LOCALSYSTEM.
Related
I'm writing my first application using MSMQ and everything works well with local queues on my development machine. I cannot seem to connect to a remote queue when I tested it.
I have 10 Windows 10 Pro installation (not domain joined, but I have also tried this on two domain joined machines), both with MSMQ installed. I have disabled the firewall on both machines, unchecked the 'Disable un-authenticated RPC calls" on both machines. Changed the permissions on the queue to full control for everyone and anonymous.
I'm using .NET and the system.messaging namespace. When I call the messagequeue constructor, I can see that most of the properties are in a exception state.
VB code New MessageQueue("FormatName:Direct=TCP:x.x.x.x\private$\test")
I found an article detailing a registry entry NewRemoteReadServerAllowNoneSecurityClient I thought might work but got the same result. I'm sure this is some sort of security issue but I have no idea what I'm doing wrong.
Anyone have any ideas? Seems like this should be much easier than I am experiencing.
I have to think this is a solved issue but I am just not getting it to work. So I have come to you StackOverflow with this issue:
I have a windows server 2016 machine running in amazon ec2. I have a machine.ps1 script in a config directory.
I create an image of the box. (I have tried with checking noreboot and unchecking it)
When I create a new instance of the image I want it to run machine.ps1 at launch to set the computer name and then set routes and some config settings for the box. The goal is to do this without logging into the box.
I have read and tried:
Running Powershell scripts at Start up
and used this to ensure user data was getting passed in:
EC2 Powershell Launch Tools
I have tried setting up a scheduled task that runs the machine.ps1 on start up (It just hangs)
I see the initializeInstance.ps1 on start up task and have tried to even coop that replacing the line to run userdata with the line to run my script. Nothing.
If I log into the box and run machine.ps1, it will restart the computer and set the computer name and then I need to run it once more to set routes. This works manually. I just need to find a way to do it automagically.
I want to launch these instances from powershell not with launch configurations and auto scale.
You can use User data
Whenever you deploy a new server, workstation or virtual machine there is nearly always a requirement to make final changes to the system before it’s ready for use. Typically this is normally done with a post-deployment script that might be triggered manually on start-up or it might be a final step in a Configuration Manager task sequence or if you using Azure you may use the Custom Script Extension. So how do you achieve similar functionality using EC2 instances in Amazon Web Services (AWS)? If you’ve created your own Amazon Machine Image (AMI) you can set the script to run from the Runonce registry key, but then can be a cumbersome approach particularly if you want to make changes to the script and it’s been embedded into the image. AWS offers a much more dynamic method of injecting a script to run upon start-up through a feature called user data.
Please refer following link for ther same:
Poershell User data
Windows typically won't let a powershell script call another powershell script unless it is being run as Administrator. It is a weird 'safety' feature. But it is perfectly okay to load the ps1 files and use any functions inside them.
The UserData script is typically run as "system". You would THINK that would pass muster. But it fails...
The SOLUTION: Make ALL of your scripts into powershell functions instead.
In your machine.ps1 - wrap the contents with function syntax
function MyDescriptiveName { <original script contents> }
Then in UserData - use the functions like this
# To use a relative path
Set-Location -Path <my location>
# Load script file into process memory
. <full-or-relpath>/machine.ps1
# Call function
MyDescriptiveName <params-if-applicable>
If the function needs to call other functions (aka scripts), you'll need to make those scripts into functions and load the script file into process memory in UserData also.
I'm trying to create a configuration, using PowerShell DSC, that would help me create a SharePoint farm using Virtual Machines. Assuming that I have a Windows 10 machine with Hyper-V installed I would like my configuration script to create the required VMs, for example DC, SPA1, SPw1, SPW2 and SPDB1, configure their network connections and connect to a domain controller (DC1), then proceed to install the SharePoint/SQL Server prerequisites and installation before going on to configure the farm, once available.
I've created configurations that complete various stages but I am unable to figure out how to connect them to work in an orchestrated manor. For example I can create the VMs or perform the install and configuration of SharePoint but I can't get these configurations to work in tandem.
Having read the DSC documentation I thought that is might be possible using composite resources but I am unable to get the configuration to continue onto the new Virtual Machine after creation.
From the composite resource documentation:
configuration RenameVM
{
Import-DscResource -Module TestCompositeResource
Node localhost
{
xVirtualMachine VM
{
VMName = "Test"
SwitchName = "Internal"
SwitchType = "Internal"
VhdParentPath = "C:\Demo\VHD\RTM.vhd"
VHDPath = "C:\Demo\VHD"
VMStartupMemory = 1024MB
VMState = "Running"
}
}
Node "192.168.10.1"
{
xComputer Name
{
Name = "SQL01"
DomainName = "fourthcoffee.com"
}
}
}
Ideally the node names would be dynamically declared in the configuration data and not explicitly defined I.P addresses. I'm also having trouble with my Hyper-V configuration creating multiple switches but that's a separate issue. So I guess my question is:
Is it possible to create a configuration that deals with the creation and advanced configuration of Virtual Machines?
The problem you are running up against is a conceptual one of what DSC does.
Reading the document that you linked, it says
Configurations are declarative PowerShell scripts which define and configure instances of resources. Upon running the configuration, DSC (and the resources being called by the configuration) will simply “make it so”, ensuring that the system exists in the state laid out by the configuration.
DSC is designed to configure an instance of a resource. At its basic level a DSC configuration is run on a single machine, configuring that machine into a specified state.
DSC scripts should be constrained to work within the boundaries of the machine that they are running on. It seems that this is part of the problem you are experiencing.
If you have two sets of scripts. A Deploy VM script, that runs against a hyper-v server and a Sharepoint build that then configures the VM once it has launched. It seems that what you are trying to do is launch the Sharepoint script from within the hyper-v deploy script. At that stage though the Sharepoint server is outside of the boundary of control of the hyper-v server (apart from its atomic VM capabilities, start,stop, delete etc)
Instead what I would suggest you do is see them as two entirely separate entities. There is no need to have a scripted connection between creating a VM and installing Sharepoint.
At a high level your pipeline would look something like this
Run deploy configuration to create a new VM. At the point where that VM is running that configuration is complete. It has no other actions.
The VM builds and starts, part of its initial configuration is to run a bootstrap script that tells it its function.
The VM contacts the DSC server, tells it its function, and requests any configurations that are available for it.
The VM downloads its configurations, and configures itself as a Sharepoint Server (or SQL Server, etc)
If there are external dependencies, i.e. you can install Sharepoint before SQL has completed, then simply have a dependson for a shared file. i.e. if \\server\share\sqlcompleted.txt exists Or whatever other mechanism fits your environment.
Building servers this way removes dependencies, it means that if you decide you want to switch to ESX then all you need to change is your deploy script. Equally if you move everything to a cloud deployment.
Is there any way using the PowerShell Azure cmdlets to get the machine name on which an Azure worker or web role is running? Specifically, I'm looking for the name that starts with "RD". I'm not 100% sure if I'm searching for this using the right terminology, because my results are clouded with information about Azure Virtual Machines. I've also been exploring the objects returned from such calls as Get-AzureDeployment and Get-AzureVM, but haven't found the "RD" name anyplace yet.
I've also found the discussion here, but wondering if it's out of date: http://social.msdn.microsoft.com/Forums/windowsazure/en-US/73eb430a-abc7-4c15-98e7-a65308d15ed9/how-to-get-the-computer-name-of-a-webworker-role-instance?forum=windowsazuremanagement
Motivation: My New Relic monitoring often complains "server not reporting" for instances that have been decommissioned. New Relic's server monitoring knows only the "RD..." names, and I'm looking for a quick way to get a list of these from Azure so that I can compare and see if New Relic is only complaining about old instances or if there's a real problem with one of the current instances.
You can actually get more significant host names than RD... by setting the vmName key in the cloud service's ServiceConfiguration file.
Then, your host names will be of the form vmnameXX, where XX is the instance number of the role. (i.e. "MyApp01", "MyApp02", ...)
For details on this, see the links below:
https://azure.microsoft.com/documentation/articles/virtual-networks-viewing-and-modifying-hostnames/
http://blogs.msdn.com/b/cie/archive/2014/03/30/custom-hostname-for-windows-azure-paas-virtual-machines.aspx
There is a public queue named queue1 on machine A. I want to send messages to this queue from machine B. In order to achieve this, I wrote that c# code.
if (MessageQueue.Exists("machineA\queue1"))
{
label1.Text = "queue found";
}
else
{
label1.Text = "queue could not be found";
}
But Exists() method return false on machine B. The same code works well on machine C.
I found somethings related with msmq domain mode and workgroup mode. I think that msmq installed in workgoup mode on machine B.
How can I change this configuration from workgroup mode to domain mode?
HKEY_LOCAL_MACHINE\Software\Microsoft\MSMQ\Parameters\
Check the data for the REG_DWORD workgroup. Is it 1 or 0?
1 is workgroup mode.
0 is AD mode
Basically the difference between domain and work group mode is not defined by the value of the registry flag "workgroup" mentioned by #engin. This flag just reflects current operational mode but doesn't set it.
Whether you run in domain or workgroup mode is defined whether you installed MSMQ on domain controller or on a member server. Details about differences between these two modes can be found here: https://support.microsoft.com/en-us/kb/884974/
MSMQ 1.0 used to support domain mode only. Current MSMQ version is 5.0.
Next you may see quite interesting behavior when you installed MSMQ on your DC, your workgroup flag continuously reverts to 1 after each MSMQ service restart. This means that you have to grant Network Service account the Create MSMQ Configuration Objects permission to the computer object in Active Directory Domain Services before installing the Directory Services Integration feature on a computer that is a domain controller.
You may find details on how to do it here:
https://technet.microsoft.com/en-us/library/cc730960.aspx
MSMQ runs under the (less privileged) Network Service account instead of (all powerful) Local System account starting from version 4.0 (Vista/Server 2008)
So to answer #mkus question more directly to "set" domain mode you just install MSMQ on domain controller and make sure that proper permissions in place for Network Service account. Once this is done you well see it operating in domain mode with workgroup flag switched to 0 automatically to reflect this.
Also couple of links to clarify issues around MSMQ objects permissions and when/why you need to set them:
http://blogs.msdn.com/b/johnbreakwell/archive/2009/08/03/default-msmq-queue-permissions-have-changed-in-msmq-4-0.aspx. In short starting from MSMQ 4.0 Everyone and Anonymous Logon were removed from default MSMQ objects ACLs as precaution against DoS attacks (though there are exlusions to this change and Workgroup mode is one of those).
And as you may read in Technet article below you need to go a grant certain rigts to MSMQ objects either to Network Service OR to Computer accounts when installing the Routing Service feature on a Windows Server 2008 R2 (or later) computer that is not a domain controller OR when installing the Directory Service Integration feature of Message Queuing on a Windows Server 2008 R2 (or later) computer that is a domain controller. See details here:
https://technet.microsoft.com/en-us/library/cc749102(v=ws.10).aspx
Run Server Manager on the machine that is hosting the queue. Right-click on Features and click "add features"
Drill down under Message Queuing and under Message Queuing Services. You should see a checkbox for Directory Service Integration.
Check it and click install.
Usually you have to reboot the server for it to show the change.
I ran into some problems, no matter how much I installed or uninstalled MSMQ or restarted, I still wasn't able to use the queue. So I wanted to post some links here
http://support.microsoft.com/kb/935498
When it gets to a part about "To work around this problem, use the Active Directory Users and Computer Microsoft Management Console (MMC)...". Below is how you do that.
How to delete from active directory
http://technet.microsoft.com/en-us/library/cc773660(v=WS.10).aspx
"Delete stale computer objects" is the part you are interested in.
I also found this nice error in the event log "The Message Queuing service will not join the domain. An MSMQ Configuration (msmq) object exists in the new domain with an ID differing from the service ID. Please delete the MSMQ Configuration object in the new domain, restart the Message Queuing service, and log on again."- which helped to point out they way.
I have face this issue for windows server 2016, where even thought I was changing registry value to domain mode "0", it reverts to "1", after server restart.
To solve the issue on OS 2016, we need to uninstall below MSMQ feature as they are deprecated from OS 2016 onward.
Message Queuing Trigger
Multicasting support
Routing Service