Thursday 22 September 2016

How to pass named parameters with Invoke-Command




-ArgumentList is based on use with scriptblock commands, like:
Invoke-Command -Cn (gc Servers.txt) {param($Debug=$False, $Clear=$False) C:\Scripts\ArchiveEventLogs\ver5\ArchiveEventLogs.ps1 } -ArgumentList $False,$True
When you call it with a -File it still passes the parameters like a dumb splatted array. I've submitted a feature request to have that added to the command (please vote that up).
So, you have two options:
If you have a script that looked like this, in a network location accessible from the remote machine (note that -Debug is implied because when I use the Parameter attribute, the script gets CmdletBinding implicitly, and thus, all of the common parameters):
param(
   [Parameter(Position=0)]
   $one
,
   [Parameter(Position=1)]
   $two
,
   [Parameter()]
   [Switch]$Clear
)

"The test is for '$one' and '$two' ... and we $(if($DebugPreference -ne 'SilentlyContinue'){"will"}else{"won't"}) run in debug mode, and we $(if($Clear){"will"}else{"won't"}) clear the logs after."
Without getting hung up on the meaning of $Clear ... if you wanted to invoke that you could use either of the following Invoke-Command syntaxes:
icm -cn (gc Servers.txt) { 
    param($one,$two,$Debug=$False,$Clear=$False)
    C:\Scripts\ArchiveEventLogs\ver5\ArchiveEventLogs.ps1 @PSBoundParameters
} -ArgumentList "uno", "dos", $false, $true
In that one, I'm duplicating ALL the parameters I care about in the scriptblock so I can pass values. If I can hard-code them (which is what I actually did), there's no need to do that and use PSBoundParameters, I can just pass the ones I need to. In the second example below I'm going to pass the $Clear one, just to demonstrate how to pass switch parameters:
icm -cn $Env:ComputerName { 
    param([bool]$Clear)
    C:\Scripts\ArchiveEventLogs\ver5\ArchiveEventLogs.ps1 "uno" "dos" -Debug -Clear:$Clear
} -ArgumentList $(Test-Path $Profile)

The other option

If the script is on your local machine, and you don't want to change the parameters to be positional, or you want to specify parameters that are common parameters (so you can't control them) you will want to get the content of that script and embed it in your scriptblock:
$script = [scriptblock]::create( @"
param(`$one,`$two,`$Debug=`$False,`$Clear=`$False)
&{ $(Get-Content C:\Scripts\ArchiveEventLogs\ver5\ArchiveEventLogs.ps1 -delimiter ([char]0)) } @PSBoundParameters
"@ )

Invoke-Command -Script $script -Args "uno", "dos", $false, $true

PostScript:

If you really need to pass in a variable for the script name, what you'd do will depend on whether the variable is defined locally or remotely. In general, if you have a variable $Script or an environment variable $Env:Script with the name of a script, you can execute it with the call operator (&): &$Script or &$Env:Script
If it's an environment variable that's already defined on the remote computer, that's all there is to it. If it's a local variable, then you'll have to pass it to the remote script block:
Invoke-Command -cn $Env:ComputerName { 
    param([String]$Script, [bool]$Clear)
    &$Script "uno" "dos" -Debug -Clear:$Clear
} -ArgumentList $ScriptPath, $(Test-Path $Profile)


from: Stack overflow

Friday 24 June 2016

Redirecting VS requests to services using fiddler

If you want to look at the traffic with Fiddler, you probably want to go the route of changing the machine.config file so that all .NET applications will send traffic through Fiddler. This helps you ensure that you capture data from processes running in services, etc. Also this is great way to save time when working with multiple services.

Expose call to fiddler 


At first we have to modify web.config by adding following.

<system.net>
      <defaultProxy
                 enabled = "true"
                 useDefaultCredentials = "true">
        <proxy autoDetect="false" bypassonlocal="false" proxyaddress="http://127.0.0.1:8888" usesystemdefault="false" />
      </defaultProxy>
    </system.net>
After this we can see requests from Visual Studio in our fiddler


Now we need to rewrite the requests

For this section we need to download  following plugin

http://www.telerik.com/download/fiddler/fiddlerscript-editor

In fiddler window is FiddlerScript tab usually on right hand side (unless you have changed it)


You can scroll or use search to find: "OnBeforeRequest". I have highlighted it for you on picture above.

Insert following snippet and modify it to what you want to use.


 // fiddler configuration to rewrite call to local instance of services
 if (oSession.HostnameIs("testservice.com")) {
         oSession.hostname = "local.testservice.com";          
 } 
           
Lets describe this:
first line  

 if (oSession.HostnameIs("testservice.com")) {
searches requests based on name and needs to be same


Second line     
this is the replacement line
         oSession.hostname = "local.testservice.com";    

Now if you run application with internal call, it will be redirected to local instance.

Advanced configuration 


You can apply the change in machine.config if you want to apply it to all applications as follows.

Open machine.config in the folder C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config. Note that if you are debugging a 64bit service (like ASP.NET) you will want to look in the Framework64 folder instead of the Framework folder. Similarly, if you are using a .NET version prior to 4.0, you will need to adjust the version part of the path.

Add the following XML block as a peer to the existing system.net element, replacing any existing defaultProxy element if present as follows:

<system.net>
      <defaultProxy
                 enabled = "true"
                 useDefaultCredentials = "true">
        <proxy autoDetect="false" bypassonlocal="false" proxyaddress="http://127.0.0.1:8888" usesystemdefault="false" />
      </defaultProxy>
    </system.net>

Friday 11 March 2016

Get all users from active directory using c#


I needed to get all members  from active directory using c#.
Now the solution I have found is as follows


using (var context = new PrincipalContext(ContextType.Domain, "yourdomain.com"))
{
    using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
    {
        foreach (var result in searcher.FindAll())
        {
            DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry;
            Console.WriteLine("First Name: " + de.Properties["givenName"].Value);
            Console.WriteLine("Last Name : " + de.Properties["sn"].Value);
            Console.WriteLine("SAM account name   : " + de.Properties["samAccountName"].Value);
            Console.WriteLine("User principal name: " + de.Properties["userPrincipalName"].Value);
            Console.WriteLine();
        }
    }
}
Console.ReadLine();
the solution I have provided is from http://stackoverflow.com/questions/5162897/how-can-i-get-a-list-of-users-from-active-directory


Now the directory entry contains properties defined as string or object and you need to make sure that the data are accessed correctly.



Wednesday 9 March 2016

C# Querying Organisational Units in Active directory

I am working on active directory queries. I have decided to share come code I have found, coded and updated.

Reference :
AD: Active Directory
OU: OrganisationalUnit (used to structure your AD)

How to get Organisational units from AD using c# & LDAP.

NOTE The important information here is:
Each structure in active directory have its own name and many times I have come across of misspelling the types. For OU we have to setup filter to search only on:

objectCategory = organizationalUnit


Now the full code is as follows


// connect to "RootDSE" to find default naming context
DirectoryEntry rootDSE = new DirectoryEntry("LDAP://RootDSE");

string defaultContext = rootDSE.Properties["defaultNamingContext"][0].ToString();

// bind to default naming context - if you *know* where you want to bind to - 
// you can just use that information right away
DirectoryEntry domainRoot = new DirectoryEntry("LDAP://" + defaultContext);

// set up directory searcher based on default naming context entry
DirectorySearcher ouSearcher = new DirectorySearcher(domainRoot);

// SearchScope: OneLevel = only immediate subordinates (top-level OUs); 
// subtree = all OU's in the whole domain (can take **LONG** time!)
ouSearcher.SearchScope = SearchScope.OneLevel;
// ouSearcher.SearchScope = SearchScope.Subtree;

// define properties to load - here I just get the "OU" attribute, the name of the OU
ouSearcher.PropertiesToLoad.Add("ou");

// define filter - only select organizational units
ouSearcher.Filter = "(objectCategory=organizationalUnit)";

// do search and iterate over results
foreach (SearchResult deResult in ouSearcher.FindAll())
{
    string ouName = deResult.Properties["ou"][0].ToString();
}
Links to Stack Overflow

http://stackoverflow.com/questions/16810382/getting-all-ous-from-a-active-directory

Tuesday 8 March 2016

System call failed. (Exception from HRESULT: 0x80010100 (RPC_E_SYS_CALL_FAILED))

One day when I have opened Visual Studio I have come across following error


System call failed. (Exception from HRESULT: 0x80010100 (RPC_E_SYS_CALL_FAILED))


This can be caused by Studio attempting to contact TFS and fails.

Resolution is simple

Ensure your connection to TFS server is correct. You can run 'ipconfig /renew' from your command to see if you have connection