Monday, December 31, 2012

Place Outlook Reminders as top window using PowerShell

Place Outlook Reminders as top window using PowerShell

NOTE: In order for this to work.
        1. It should be in a powershell window and it should not be closed.
        2. Must be run with Admin Privledges.
(For information about WmiEvents read this great site:http://www.ravichaganti.com/blog/?p=1509)
#There are 2 parts to this program. 1. Set up the triggers for when outlook gets opened in the future.
#                                   2. Set up the triggers when outlook is already opened.
try{
#Connect reciever if Outlook is not yet open#
#Create a Trigger which will execute code when a program called 'OUTLOOK.EXE' starts#
Register-WmiEvent -Query "Select * from Win32_ProcessStartTrace WHERE ProcessName='OUTLOOK.EXE'"   `
                  -SourceIdentifier "OutlookProcess"                                               `
                  -Action {     #Get the process ID which is assigned to the Outlook program
                                $ProcessID = $Event.SourceEventArgs.NewEvent.ProcessID;
                                #Create a Trigger which will execute when Outlook starts a new thread#
                                Register-WmiEvent -Query "Select * from Win32_ThreadStartTrace WHERE ProcessID=$ProcessID"   `
                                                  -SourceIdentifier "OutlookThread"                                          `
                                                  -Action {      #Get the threads parent process (The window that started this thread) so we can see if the title on the window has labeled with "Reminder" in it.
                                                                 $ThreadsParentProcess = Get-Process -id $($Event.SourceEventArgs.NewEvent.ProcessID);      
                                                                 if($ThreadsParentProcess.MainWindowTitle.Contains("Reminder")) {
#Expose this C++ method that puts a specified window as the top most window using C# code                                                                
Add-Type @"
  using System;
  using System.Runtime.InteropServices;
  public class WindowStatus {
     static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
     const UInt32 SWP_NOSIZE = 0x0001;
     const UInt32 SWP_NOMOVE = 0x0002;
     const UInt32 TOPMOST_FLAGS = SWP_NOMOVE | SWP_NOSIZE;
     [DllImport("user32.dll")]
     [return: MarshalAs(UnmanagedType.Bool)]
     public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
     public static void OnTop(IntPtr hWnd) {
            SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS);
     }
  }
"@;                    
                                                                      #Call the C# Method that we created in the above statement to place this threads parent process as the top most window.
                                                                      [WindowStatus]::OnTop( $ThreadsParentProcess.MainWindowHandle);
                                                                 }
                                                                 #Remove(Dispose) the $ThreadsParentProcess variable from memory#
                                                                 $ThreadsParentProcess.Dispose();
                                                          }
                                #Force garbage collection to run to make double sure that we have no residue in memorey#
                                [GC]::Collect();
                                #Create a Trigger which will execute when Outlook is closed to remove the triggers we created#
                                Register-WmiEvent -Query "Select * from Win32_ProcessStopTrace WHERE ProcessID=$ProcessID"   `
                                                  -Action {     Unregister-Event -SourceIdentifier "OutlookThread" ; }
                           }
}                          
catch{}                      

#Connect reciever if Outlook is already open#
try{ $ProcessID = $(Get-Process |?{$_.Name -eq "OUTLOOK" } |select Id).Id }
catch{}
if($ProcessID -gt 0) {
                                #Create a Trigger which will execute when Outlook starts a new thread#
                                Register-WmiEvent -Query "Select * from Win32_ThreadStartTrace WHERE ProcessID=$ProcessID"   `
                                                  -SourceIdentifier "OutlookThread"                                          `
                                                  -Action {      #Get the threads parent process (The window that started this thread) so we can see if the title on the window has labeled with "Reminder" in it.
                                                                 $ThreadsParentProcess = Get-Process -id $($Event.SourceEventArgs.NewEvent.ProcessID);      
                                                                 if($ThreadsParentProcess.MainWindowTitle.Contains("Reminder")) {
#In order to expose this C++ method that puts any specified window as the top most window we have to use C# code                                                                 
Add-Type @"
  using System;
  using System.Runtime.InteropServices;
  public class WindowStatus {
     static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
     const UInt32 SWP_NOSIZE = 0x0001;
     const UInt32 SWP_NOMOVE = 0x0002;
     const UInt32 TOPMOST_FLAGS = SWP_NOMOVE | SWP_NOSIZE;
     [DllImport("user32.dll")]
     [return: MarshalAs(UnmanagedType.Bool)]
     public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
    public static void OnTop(IntPtr hWnd) {
            SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS);
     }
  }
"@;                    
                                                                      #Call the C# Method that we created in the above statement to place this threads parent process as the top most window.
                                                                      [WindowStatus]::OnTop( $ThreadsParentProcess.MainWindowHandle);
                                                                 }
                                                                 #Remove(Dispose) the $ThreadsParentProcess variable from memory#
                                                                 $ThreadsParentProcess.Dispose();
                                                          }
                                #Force garbage collection to run to make double sure that we have no residue in memorey#
                                [GC]::Collect();
                                #Create a Trigger which will execute when Outlook is closed to remove the triggers we created#
                                Register-WmiEvent -Query "Select * from Win32_ProcessStopTrace WHERE ProcessID=$ProcessID"   `
                                                  -Action {     Unregister-Event -SourceIdentifier "OutlookThread" ; }
   
}

Retrieve Windows event information using powershell

Retrieve Windows event information using powershell

An amazing site that has a lot of this information is located here. http://www.ravichaganti.com/blog/?p=1711

To display events that you can attach a script/program to type the following command:
Get-WMIObject -Query "Select * from meta_class Where (__This ISA '__Event') AND (__Class like 'win32%')"

To look at a process save it into an object variable. (For example we'll look at Win32_ProcessStartTrace)
$ProcessStart = Get-WMIObject -list -Class Win32_ProcessStartTrace

 
To display the properties that you can query on type the command below.
$ProcessStart.Properties |select Name
 
The results should look like the following.
Name
----                                                                                                                                                        
ParentProcessID                                                                                                                                             
ProcessID                                                                                                                                                   
ProcessName                                                                                                                                                 
SECURITY_DESCRIPTOR                                                                                                                                         
SessionID                                                                                                                                                   
Sid                                                                                                                                                         
TIME_CREATED 
 
Now that you know the events and its property names you can attach an action to any specific process.  
#Register-WMIEvent using -Query
Register-WmiEvent -Query "Select * from Win32_ProcessStartTrace WHERE ProcessName='notepad.exe'" `                   -Action {Write-Host $Event.SourceEventArgs.NewEvent.ProcessName " New Outlook process created" }
 

How To Deploy applications to IIS using Powershell

How To Deploy applications to IIS

#Additional information on deploying to IIS here http://www.iis.net/learn/manage/powershell/powershell-snap-in-creating-web-sites-web-applications-virtual-directories-and-application-pools
$from = "c:\temp\WebApp\*"
$name = "WebApp"
$to = "C:\inetpub\wwwroot\"+$name+"\"
$physicalPath = $to
#Move the Web Application to the IIS folder
Copy-Item $from $to -recurse -Force

###### Create an application pool and ensure it is using .NET 4   #######
    New-WebAppPool -Name $name -Force
    #To Get The Web Application Object again use the following statement ####$webPool = Get-Item IIS:\AppPools\$name
    $webPool = Get-Item IIS:\AppPools\$name
    $webPool.managedRuntimeVersion = "v4.0"
    $webPool.managedPipelineMode = "Classic"
    $webPool.processModel.loadUserProfile =$true
    $webPool.processModel.logonType = "LogonBatch"
    #If Identity type is ApplicationPoolIdenetity/NetworkService/LocalService/LocalSystem uncomment
    #the Line bellow and comment out the other identityType="SpecificUser,UserName and Password lines
    #$webPool.processModel.identityType = "ApplicationPoolIdentity"
    $webPool.processModel.identityType = "SpecificUser"
    $webPool.processModel.userName = "Gtank1"
    $webPool.processModel.password = "Password1"
    $webPool | Set-Item

    # Create Website
    New-WebSite -Name $name -Port 80 -HostHeader $name -PhysicalPath $physicalPath -Force
    #To Get The Web Site Object again use the following statement #### $WebSite = Get-Item IIS:\Sites\$name
    # Set the Application Pool
    Set-ItemProperty IIS:\Sites\$name ApplicationPool $name
    #Turn on Directory Browsing
    Set-WebConfigurationProperty -filter /system.webServer/directoryBrowse -name enabled -Value $true -PSPath IIS:\Sites\$name
    #Only add the default document if it already hasn't been added
    $DefaultDocument = "Accounts/Default.aspx"
    $ExistingDefaultDocuments = get-webconfigurationproperty -filter /system.webServer/defaultDocument -name files -Location $name #Retrieve all the default documents
    $DefDocFound = $ExistingDefaultDocuments.Collection | where {$_.value -eq $DefaultDocument} #look for the default document that we want to add
    if(!$DefDocFound) {
            #To add the default document globally remove the -Location parameter
            Add-webconfigurationproperty -filter /system.webServer/defaultDocument -name files -value @{value=$DefaultDocument} -Location $name
            #remove-webconfigurationproperty /system.webServer/defaultDocument -name files -atElement @{value=$DefaultDocument} -Location $name
    }
    #Add-WebConfiguration -filter /system.webServer/defaultDocument/files -name enabled -location $name -value @{value="default.aspx"}
    # Update Authentication
    Set-WebConfigurationProperty -filter /system.WebServer/security/authentication/AnonymousAuthentication -name enabled -value true -location $name
    Set-WebConfigurationProperty -filter /system.WebServer/security/authentication/windowsAuthentication -name enabled -value false -location $name
    Set-WebConfigurationProperty -filter /system.WebServer/security/authentication/basicAuthentication -name enabled -value false -location $name
#The code beolow will actually delete the Application pool and Web site that has been created above.
#NOTE:  You must delete the site and application pools that are retrieved from the Servermanager object
#       instead of using get-item otherwise you will get the following error "The configuration object is read only, because it has
#       been committed by a call to ServerManager.CommitChanges(). If write access is required, use ServerManager
#       to get a new reference."
#
<#
   [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Web.Administration")
   $iis = New-Object Microsoft.Web.Administration.ServerManager
   Remove-Item $to -recurse -Force
   $WebSite = $iis.Sites["WebApp"]
   $webPool = $iis.ApplicationPools["WebApp"]
   $WebSite.Delete()
   $webPool.Delete()
#>

Create a Group and User using Powershell

Create a Group and User using Powershell

$cmpName = [System.Net.DNS]::GetHostName()
#Load the Computer WinNT(Windows New Technology) into an ADSI (Active Directory Service Interface) defined object.
$computer = [ADSI]("WinNT://$cmpName,computer")
#Join the computer to the Home network named WorkGroup
$computer.JoinDomainOrWorkgroup("WORKGROUP")

#List all the computers users and groups
$computer.Children | Where {$_.SchemaClassName -ne "service"} | Select *Name

#Create A Family Group
$newGroup = $computer.Create("group","Family")
$newGroup.psbase.InvokeSet("description","Family Group")
$newGroup.setinfo()

#Give the Family Group (which includes all members) to the Admin group
$adminGroup = "$cmpName/Administrators,group"
$adminGroup = [adsi]("WinNT://$adminGroup")
$adminGroup.add("WinNT://$cmpName/Family")

#Create a new user
$newuser = $computer.Create("user", "Test")
$newuser.SetPassword("Password1")
$newuser.SetInfo()
$newuser.psbase.InvokeSet('AccountDisabled', $false)
$newuser.psbase.InvokeSet('FullName','FirstName LastName')
$newuser.SetInfo()

#Add user to the Family group
$newGroup.psbase.Invoke("Add","WindNT://"+$newuser.Name)

#List all the groups and users on this computer
$computer.Children | Where {$_.SchemaClassName -eq "group" -or $_.SchemaClassName -eq "user"} | Select SchemaClassName, Name , Path

Order of Priority When Accessing a URL

Order of Priority When Accessing a URL

When accessing web sites the URL address is checked in 3 places prior to accessing it online.
Your computer is defaulted to check in this order:
1. DNS Resolver Cache: 
        a. You can view the contents by opening a PowerShell window and typing: Get-DnsClientCache
        b. You can clear it by typing IPConfig /flushDNS
2. Hosts File:
        a. It is located in C:\Windows\System32\Drivers\etc\Hosts.
        b. You can add custom DNS entries in the hosts file. (creates a custom URL address to a particular URL)
        c. The same web server can have the appearance of hosting multiple domain names on port 80 if a unique host header name is set.  In order to access this site for the new address defined in the host header the Hosts file can be updated to declare the IP address and the domain name.  This is a good first test prior to requesting/implementing a change to the DNS. 

3.DNS
        a.  Stores the same information as what is in the local hosts file but is accessed by all computers/users on the current domain.
4.WINS

Read here to learn how to change the order of this list by tweaking your registry.  http://www.speedguide.net/articles/host-resolution-priority-tweak-1130

Thursday, November 22, 2012

C# How to keep your system from entering sleep mode when running long programs


//Need to include the System.Runtime.InteropServices in order to use the [DllImport] attribute
using System.Runtime.InteropServices;

namespace MyAmazingProgram
{
    public class MyApplication
    {

         //Enable away mode and prevent the sleep idle time-out. For more information read here. http://msdn.microsoft.com/en-us/library/aa373208%28v=vs.85%29.aspx
        SystemState.SetThreadExecutionState(SystemState.ES_CONTINUOUS | SystemState.ES_SYSTEM_REQUIRED | SystemState.ES_AWAYMODE_REQUIRED);
         
        //Execute long running code here...
        // Clear EXECUTION_STATE flags to disable away mode and allow the system to idle to sleep normally.
        SystemState.SetThreadExecutionState(SystemState.ES_CONTINUOUS);
     

    }  
    internal static class SystemState
    {
        // Import SetThreadExecutionState Win32 API and all flags
        [DllImport("kernel32.dll")]
        public static extern uint SetThreadExecutionState(uint esFlags);

        public const uint ES_SYSTEM_REQUIRED = 0x00000001;
        public const uint ES_DISPLAY_REQUIRED = 0x00000002;
        public const uint ES_USER_PRESENT = 0x00000004;
        public const uint ES_AWAYMODE_REQUIRED = 0x00000040;
        public const uint ES_CONTINUOUS = 0x80000000;
    }
}

Saturday, October 13, 2012

C# Attributes

C# Attributes [attribute] - Java referes to this as Accessors @accessor

Attributes are used to define additional functionality to methods ,classes properties, etc. Here is the full list that you can assign attributes to.
You can do a variety of things using attributes (custom or already made) such as validate fields, change the return value, add metadata, etc.

Some examples of using attributes are when Linq to SQL assigns classes to a Table or assignes properties to table columns.
[Table(Name="Orders")]
class Order
[Column(Name="OrderDate", CanBeNull=true)]
 public DateTime? OrderDate { get; set; }


Basic information on creating custom attributes can be read here.
A great example of how you can validate fields using attributes is here.
A great example of reading the assigned attributes values can be read here or here.