Michael O'Dea-Jones' Blog

  • User Account Control Filtering on Workgroup Causes Access Denied for Remote WMI Queries

    User Access Control (UAC) filtering causes WMI scripts to run under the standard user token unless the script is run in elevated privilege mode aka "run as Administrator." There is a further complication. If the target machine is not attached to a domain (aka workgroup), the WMI query is submitted remotely, the query is run under an administrative account but not "The Administrator" then UAC filtering kicks in and the WMI query is not run with elevated privileges. Depending on the WMI query UAC Filtering may cause an "Access Denied" exception to be thrown.

    If the remote WMI query is run with "The Administrator's" credentials then the query succeeds. Not all WMI queries need to be run in elevated privilege mode as the permissions required depend on the objects and data requested by the WMI query. In my case I was requesting the status of a Windows Service and a remote authenticated user only has SC_MANAGER_CONNECT access rights even if the user is a member of the local administrators group.

    The solution is to turn off UAC. Then the remote WMI query is run in elevated privilege mode and query succeeds. Let me reiterate that this is the solution if the machine is not a member of a Domain, the user account is a local administrator but not "The Administrator" and security on the objects/data requires elevated privileges.

    The test configuration was two fully patched Windows 7 Ultimate machines in a workgroup with the firewalls off and these Services set to start automatically and were started:

    • DHCP Client
    • Remote Procedure Call (RPC)
    • Remote Procedure Call (RPC) Locator
    • RPC Endpoint Mapper
    • TCP/IP NetBIOS Helper
    • Windows Management Instrumentation

    The WMI query was run under a local administrative user but not "The Administrator" on the target machine.

    There could be an alternative solution which to give the user account privileges on the object. This would mean that UAC could remain on. In my case it would involve giving the non-administrative account permission to enumerate the Services in through the Service Control Manager (SCM). I have not tried this and there is the possibility that some of the Services will require Administrative privileges anyway. Here is a blog I came across that explains more: http://waynes-world-it.blogspot.com.au/2009/10/service-control-manager-security-for.html

  • SMO Impersonate Windows Account in a Workgroup

    A colleague of mine posted how to get SMO to Impersonate a Windows Account and I haven't been able to make it work until now. In my case I was testing SMO impersonation of a Windows account in a Workgroup, not a Domain. Here is how I managed to get SMO Windows impersonation working in a Workgroup:

    • Configured the host and target machines to be in the same Workgroup e.g. WORKGROUP
    • Created local user accounts with the same name on the host and target machines e.g. HOST\FRED, TARGET\FRED
      • I added the local user accounts (HOST\FRED, TARGET\FRED) to the Administrators groups (HOST\Administrators, TARGET\Administrators) on their respective machines
      • Both user accounts had the same password
    • Created a SQL Login on the TARGET SQL Server Instance for the target user account (TARGET\FRED) with sufficient privileges to perform the SMO operation e.g. Grant SysAdmin role to TARGET\FRED
    • Did not specify a Domain in the username e.g. FRED not FRED@TARGET

    The test configuration was:

    • Two fully patched Windows 7 Ultimate machines in a workgroup
    • SMO Assembly Version 10.0.0.0, File Version 10.50.2500.0
    • SQL 2008 R2 Version 10.50.2500.0

    Here is the code that worked for me:

    using System;

    using Microsoft.SqlServer.Management.Smo;

    namespace SmoWindowsImpersonationTest

    {

    public class SmoWindowsImpersonationTester

    {

    public string Test()

    {

    string svrName = "TARGET";

    string userName = "FRED";

    string password = "**********";

    string result = null;

    try

    {

    Server svr = new Server(svrName);

    svr.ConnectionContext.ConnectAsUser = true;

    svr.ConnectionContext.ConnectAsUserName = userName;

    svr.ConnectionContext.ConnectAsUserPassword = password;

    svr.ConnectionContext.ServerInstance = svrName;

    svr.ConnectionContext.ApplicationName = "SmoWindowsAuthTester";

    var processors = svr.Processors;

    svr.ConnectionContext.Disconnect();

    result = "Connected. Processors = " + processors;

    }

    catch (Exception ex)

    {

    result = "Could not connect: " + Environment.NewLine + "Message: " + ex.Message;

    }

    return result;

    }

    }

    }

  • Maintenance Page for SQL Server Reporting Services 2008 Web Site

    Question: How to you display a maintenance page on a public facing Microsoft SQL Server Reporting Services (SSRS) 2008 web site when the site was undergoing maintenance?

    Answer: By dropping a web page called "app_offline.htm" into the SSRS "ReportManager" and "ReportServer" folders.

    Explanation: SSRS 2008 uses ASP.Net to host its Report Manager web site and Report Server web services under the "C:\Program Files\Microsoft SQL Server\MSRS10.MSSQLSERVER\Reporting Services" folder (for default installations). ASP.Net monitors the web sites folder for the presence of the "app_offline.htm" web page. When ASP.Net detects the "app_offline.htm" web page it shuts down the web site and displays the contents of the "app_offline.htm" web page.

    After the web site administrator has finished their maintenance all they have to do is rename the "app_offline.htm" web page to "app_offline.html" and ASP.Net will start the web site up again.

    SSRS has two web sites: Report Manager and Report Server. This means that the "app_offline.htm" web page has to be deployed to both web sites in order to bring the SSRS web site down for maintenance.

    If you only take the Report Manager web site offline then users will still be able to access the Report Server web site. If you only take down the Report Server web site then users will receive an error message when using the Report Manager web site as it relies extensively on the Report Server web services which are down.

    Note: There is some delay between when the "app_offline.htm" web page is deployed and when ASP.Net takes the web site offline. There is also a delay between when the "app_offline.htm" web page is renamed to "app_offline.html" and the web site is brought online.

    My Solution: I decided that I didn't want to wait in either scenario and created a Windows Forms Application that automates the take offline and bring online processes. Apart from renaming the "app_offline.htm" web page the key was restarting the SSRS Windows Service after the web site was taken offline or brought online. This caused the "app_offline.htm" web page to be displayed immediately after the SSRS web site was taken offline. It also caused the SSRS Report Manager and SSRS Web Server web sites to be displayed immediately after the SSRS sites were brought online.

  • An Instance of the Service is Already Running

    Right in the middle of a "simple" job I receive the error "An Instance of the Service is Already Running" from what I thought was tried and trusted code:


    using (ServiceController windowsService = new ServiceController(serviceName))
    {
        if (windowsService.Status == ServiceControllerStatus.Running)
       
    {
            windowsService.Stop();
           
    windowsService.Start(); 
        
    }
    }

     

    The exception was raised when ServiceController.Stop() was invoked. The Windows Service that I was trying to restart was an instance of Microsoft SQL Server Reporting Services (SSRS) 2008. After some searching I discovered to my surprise that the .Net ServiceController will return once the service implementation claims the Windows Service has stopped. This can be before the owning process has released all its resources and exited. Long story short the following code is what I managed to get working:

    using (ServiceController windowsService = new ServiceController(serviceName))

        windowsService.Refresh(); 
        if (windowsService.Status == ServiceControllerStatus.Running) 
        { 
             windowsService.WaitForStatus(ServiceControllerStatus.Running);
             windowsService.Stop(); 
             windowsService.WaitForStatus(ServiceControllerStatus.Stopped);
             windowsService.Start(); 
             windowsService.WaitForStatus(ServiceControllerStatus.Running); 
         }
    }

    I no longer receive the error "An Instance of the Service is Already Running". Happy days J

  • The ReportViewer Control that ships with Visual Studio 2008 can't render SSRS 2008 reports in local mode


    The ReportViewer Control that ships with Visual Studio 2008 can't render SSRS 2008 reports "in local mode" as it has the same report processing engine as SQL Server 2005. Here is the error that I was getting:

    The report definition is not valid.

    Details: The report definition has an invalid target namespace 'http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition' which cannot be upgraded.

    Solution:

    Host the SSRS reports in SSRS 2008 and change to remote mode or downgrade your reports to 2005.

  • A relationship is being added or deleted from an AssociationSet ‘x’ EF issue

    I'm still cutting my teeth on the Entity Framework (EF) and have just worked out why I have been receiving this kind of exception:

    A relationship is being added or deleted from an AssociationSet 'FK_Shift_ShiftStatus'. With cardinality constraints, a corresponding 'Safety_Shift' must also be added or deleted.

    Here is the code:

    shift.Status = context.ShiftStatuses.First(x => x.Id == Status.ShiftStartedId);

    EF Model:

    Shift * <=> 1 ShiftStatus

    Database:

    Shift.ShiftStatusId has a Foreign Key Relationship with ShiftStatus.Id

    After searching the Internet, I was none the wiser. I thought that maybe there was something theoretical that I was missing. In fact the only mistake I had made was that I didn't load the Shift Status reference before assigning it:

    shift.StatusReference.Load();

    shift.Status = context.ShiftStatuses.First(x => x.Id == Status.ShiftStartedId);

     

  • SyncToy 2.0

    Over the Christmas period I managed to nail one of my TODO's: "organise outlook, documents, music and pictures on the two home computers". This TODO has been around for years and I finally nailed it. Like so many TODO's in my life, many get put off and I never seem to get around to doing them because I have to set aside time to think, investigate, try a few options, decide and then actually do it.

    My biggest fear was that I would lose those precious e-mails, documents, music or photos. My second greatest fear was that I was going to spend eternity comparing files and folders to work out which was the most recent. My third fear was that I would be doomed to repeat this process every year or couple of years and I wanted a permanent solution. I also had a couple more fears but I think I'll stop there J

    The first solution I thought of was to write my own file and folder sync tool but I quickly got over that urge. So, rather than think about it and come up with a plan I just started doing stuff. After manually syncing for a few hours I started to get lazy. The temptations to "throw in the towel" or to "move files and hope for the best" were growing. So I stopped myself and Googled. That's when I discovered Microsoft SyncToy.

    Originally the Laptop was the definitive source and then I copied all the content onto the Desktop. Now, some years later both systems are out of sync. I have my work and Mobile Phone photos on the Desktop and the Digital Camera photos and Katie's (my wife) documents on the Laptop. SyncToy allowed me to set up folder pairs and sync my documents, music and pictures on the two home computers. SyncToy never deletes anything; it just moves them to the Recycle Bin. SyncToy also lets you to preview it's proposed changes before making them. That way you can see exactly what's going to happen. That was fear No.1 sorted.

    The beauty of SyncToy is that you just click a button and it takes care of the rest. It can even be scheduled by using the command line version of SyncToy! That was fear No.2 sorted. Using SyncToy has provided me with a way to keep the two shared folders in sync so I never have to manually sync files again! That's fear No.3 sorted.

    I'm a programmer and a lot of this work was system admin work. At times I wished I did more system admin units at Uni. Come to think of it I didn't do any! I think that half the battle was working out how the family's digital information was going to be shared, stored and backed up. I've decided that all I need now is a Networked Storage Device (NAS) that plugs into my router. Then I could store all the documents, music, photos and videos in one place to save disk space and use SyncToy to contribute documents, music and photos from our profiles no matter what computer we are using. I'll just put that on my TODO list!

    Suggestion: Have a look at the SyncToy white paper.

     

    Humm, all I have to do is put that on the TODO list!

  • Happy Dreaming!

    For those who have DreamScene and have never tried it I recommend you do. I just did and it's cool! If like me you didn't know how to set it up then check out http://windowshelp.microsoft.com/Windows/en-US/Help/51a8bdac-cd66-4ae3-afdf-6c6dcf804b991033.mspx. Now I'm going to have to get a bigger monitor, find or make a video or two, and work out a way to organise Visual Studio so that I can see the desktop once in a while! Maybe I just need a second monitor!

  • Hermes: A Midrange Alternative

    One thing that I've learned as a programmer is that nothing is easy. Or to put it another way, there is a lot of hidden work in software development. To explain consider this scenario: a client needs an FTP site checked regularly and content downloaded, validated, transformed and delivered to an internal system. When you break each step down, none of them are "intellectually" difficult to understand. However when you go to design, code, test and push the system into production you can be held up by many hidden gotchas.

    When I was learning how to program at University I totally embraced testing, documentation, reuse, patterns and practices. My Holy Grail was Rapid Application Development (RAD). My entire programming career I have attempted to write bug free, well documented, reusable code according to best practice. I have tried to keep up with the new technologies, programming paradigms, manage teams, clients and projects. I now realise that my search for the Holy Grail has taken a heavy toll on me, my employers, their projects and their bank balance. I'm left feeling somewhat dissatisfied because it generally takes me longer than I expected to get "intellectually" simple programs into production.

    My dissatisfaction, my search for the Holy Grail and a project at Wardy IT has given birth to Hermes (Greek God of Messaging): a pluggable program that hosts .Net classes called Plugins. I've been developing Hermes on and off for the past five months and am amazed at how simple, elegant and powerful it is. Hermes comes with its own suite of Plugins and the beauty of it is that you can write your own Plugins and load them into Hermes – WOW! So what's so amazing?

    1. Hermes provides a framework for me to work within, removing certain design decisions from me and allowing me to focus on core functionality.
    2. Hermes provides consistent logging and scheduling Interfaces.
    3. Hermes is pluggable. Plugins can be started, stopped and hot swapped or replaced through the Hermes Manager client.
    4. Hermes allows me to expose my programs (as WCF Services) to the enterprise and beyond.
    5. Hermes provides a centralised midrange platform, simplifying maintenance and supporting SOA architecture.
    6. Hermes has built in reports that you can use to analyse, track performance and troubleshoot.
    7. Hermes provides a test harness which makes it easy for programmers to test and debug their Plugins.
    8. Hermes can be hosted in Windows Services, Command Line, Windows and WPF Form applications.
    9. Hermes is built with the latest .Net Framework (3.5).
    10. Hermes Plugins can be written in any .Net Language.

    How many times have you reinvented the wheel? How many times have you duplicated code? How many times have you had to duplicate systems because you can't reuse them? How many times have you sat at your desk, massaging your head weighing up the design considerations? How many programs have you written that don't log? How hard does that make it to debug/troubleshoot? How many times have you thought that your systems are too hard to manage? How many times have you thought that I'm the only one who knows this stuff? How much better could you systems be if you had good performance statistics?

    If you are like me the score card isn't that great but you gave it your best shot. Well imagine if you could go RAD, go SOA, take control. Would you reinvent the wheel? I doubt it! Let's use the FTP scenario above to demonstrate the benefits of using Hermes. Hermes ships with an FTP Watcher which can be scheduled to download files. When the FTP Watcher Plugin detects a new file it downloads it and submits a job to the Scheduler which distributes the job to the appropriate FTP Processing Plugin. Since the file format, validation, transformation and delivery is unique to your business, you write the core logic in the FTP Processing Plugin. You test it in the Test Harness and when satisfied load it into Hermes. With the flick of a switch you activate the FTP Watcher and Processor Plugins and you now have a system running 24x7 processing all FTP deliveries. Any errors can be monitored in real time by MOM or SCOM or sent to an e-mail address or mobile. All the jobs can be viewed in Hermes Manager and rescheduled if needed. It's all too easy! Didn't I just say nothing is easy?

  • Previous Versions of a File/Folder under Vista

    Did you know that when enabled, select versions of Microsoft Vista store previous copies of your files and folders? This means that you can get them back if you need them.

    To view the previous versions of a folder open Windows Explorer, navigate to the folder, right click on the folder and select Properties. Then select the Previous Versions tab e.g. Link.

    To view previous versions of a File just right click on the file and select "Restore previous versions".

    Check this video out for an indepth treatment of Previous Versions Link

  • What to do when Visual Studio can’t create Private Accessors in your Unit Tests

    I came across this issue recently when trying to create unit tests with Microsoft Visual Studio 2008 SP1. Test stubs were created for the Public methods of the class but VS2008 could not create a Private Accessor for the Private methods e.g.:

    /// <summary>

    ///A test for TrimTimeOffDate

    ///</summary>

    [TestMethod()]

    [DeploymentItem("WardyIT.Services.Hermes.Plugins.dll")]

    public void TrimTimeOffDateTest()

    {

    // Creation of the private accessor for 'Microsoft.VisualStudio.TestTools.TypesAndSymbols.Assembly' failed

    Assert.Inconclusive("Creation of the private accessor for \'Microsoft.VisualStudio.TestTools.TypesAndSy" +

    "mbols.Assembly\' failed");

    }

    After Googling I came across a site that talked about running Visual Studio as Administrator on Microsoft Vista. To do this I right clicked on the Visual Studio 2008 menu item and selected "Run as administrator". Once I did this the Private Accessors were successfully created e.g.:

    /// <summary>

    ///A test for TrimTimeOffDate

    ///</summary>

    [TestMethod()]

    [DeploymentItem("WardyIT.Services.Hermes.Plugins.dll")]

    public void TrimTimeOffDateTest()

    {

    SchedulingEngine_Accessor target = new SchedulingEngine_Accessor(); // TODO: Initialize to an appropriate value

    DateTime DateToTrim = new DateTime(); // TODO: Initialize to an appropriate value

    DateTime expected = new DateTime(); // TODO: Initialize to an appropriate value

    DateTime actual;

    actual = target.TrimTimeOffDate(DateToTrim);

    Assert.AreEqual(expected, actual);

    Assert.Inconclusive("Verify the correctness of this test method.");

    }

    Other suggestions were:

    1. It's bad practice to test Private Methods. Link
    2. It's bad practice to have too many classes because you have split out Private Methods into new classes. Link
    3. To use the PrivateObject Class if you can't use the Private Accessor. Link

    Other Links:

    A Unit Testing Walkthrough with Visual Studio Team Test

  • Want to script Data? The SQL Database Publishing Wizard is your friend!

    Guess what I discovered today? The SQL Database Wizard for Visual Studio! This solves the age old problem of scripting your database structure so that you can create your database on a remote/hosted server. What's more the SQL Database Wizard also has the capability to script your data as well. Yes, you heard right, script your data as well!

    Version 1.2 of the SQL Database Publishing Wizard was incorporated into Visual Studio 2008 RTM because it was a very popular add-in for Visual Studio 2005. It has subsequently been upgraded to 1.3 in Visual Studio 2008 Service Pack 1 and you can use it to script databases for SQL 2000, 2005 and 2008 Servers. You can script Data only, Structure only and Data and Structure. Check it out on the Visual Developer Team or Scot Guthrie's Blogs. For those in Visual Studio 2005 you can download the Microsoft SQL Server Database Publishing Wizard 1.1.

    The one question I have is "Why didn't someone tell me about this sooner?"

  • TabPage.Hide() doesn’t Hide the TabPage

    Here's something that just got me. The TabPage.Hide() method doesn't hide the TabPage. You have to remove the TabPage from the TabControl.TabPages collection:

    ProductTabControl.TabPages.Remove(PurchasingTabPage);

    Top, Height, Left, Width and Show have no effect too. Read more on MSDN.

  • Bankers Rounding. Don’t Bank on it. It’s the Default.

    They say you learn something new every day. In IT I learn at least a dozen new things every day. Did you know that there are two different rounding methods in .Net? I didn't. Now I've come across them in two different applications in the same week. They are To Even (Bankers) and Away from Zero.

    To Even: When a number is halfway between two others, it is rounded toward the nearest even number.

    Away From Zero: When a number is halfway between two others, it is rounded toward the nearest number that is away from zero.

    The default MidpointRounding method is MidpointRounding.ToEven. The following are equivalent and both return 0D:

    Double roundedValue = Math.Round(0.5D)
    Double roundedValue =
    Math.Round(0.5D, MidpointRounding.ToEven)

    When MidpointRounding.AwayFromZero is specified then the result is 1D:

    Double roundedValue = Math.Round(0.5D, MidpointRounding.AwayFromZero)

  • The Mo Stays. The Hair Goes.

    Just in case you didn't know, I have been growing a moustache as part of Movember. I would now like to introduce you to my Mo. This is the first moustache I have ever grown and I am quite proud of my effort. Apart from the dribbling, it's a great companion. I have also decided to keep my hair short. Some of the things people have said about my Mo:

    • With the orange shirt and no hair, you look totally prisoner, man!
    • It suites you.
    • You look artistic.
    • You remind me of Fu Manchu. And you laugh like him too!
    • You just scared the hell out of me!!!!!!! WOW. Like the Mo but I have to ask where is your hair?
    • Does your hair grow at different rates on various parts of your head?
    • I'm thinking you've just transplanted it from your scalp to your upper lip!

    So far I have raised enough money that they sent me a shaving kit! I had fun. No one got hurt. Money was raised. Now I'm scary on the outside too!

    To donate to my Mo you can either:

    1. Click this link:  https://www.movember.com/au/donate/donate-details.php?action=sponsorlink&rego=1851911&country=au and donate online using your credit card or PayPal account, or
    2. Write a cheque payable to 'Movember Foundation', referencing my Registration Number 1851911 and mailing it to:

    Movember Foundation
    PO Box 292
    Prahran VIC 3181

    Remember, all donations over $2 are tax deductible.

    The money raised by Movember is used to raise awareness of men's health issues and donated to the Prostate Cancer Foundation of Australia and beyondblue - the national depression initiative. The PCFA and beyondblue will use the funds to fund research and increase support networks for those men who suffer from prostate cancer and depression.

    Did you know:

    • Depression affects 1 in 6 men....most don't seek help. Untreated depression is a leading risk factor for suicide.
    • Last year in Australia 18,700 men were diagnosed with prostate cancer and more than 2,900 died of prostate cancer - equivalent to the number of women who will die from *** cancer annually.

    Movember is proudly grown by Holden and Schick.

    Movember is proud partners with the Prostate Cancer Foundation of Australia and beyondblue - the national depression initiative.

More Posts Next page »