Custom build task is not deleted - tfs

I'm trying to delete a Build Task using tfx-cli.
C:\Users\Work>tfx build tasks list
TFS Cross Platform Command Line Interface v0.4.11
Copyright Microsoft Corporation
id : 122d5ad0-61a1-11e6-b9c1-5b12bd371fa9
name : VersionAssembly
friendly name : Version Assembly
visibility : Build
description : Update the assembly version number to match the build number
version : 1.0.9
I now have the Task ID.
C:\Users\Work>tfx build tasks delete --task-id 122d5ad0-61a1-11e6-b9c1-5b12bd371fa9
TFS Cross Platform Command Line Interface v0.4.11
Copyright Microsoft Corporation
Task 122d5ad0-61a1-11e6-b9c1-5b12bd371fa9 deleted successfully!
But even after a Ctrl+F5 Refresh, the task still shows up in TFS:
Running the delete command again shows the same thing. Success. Not "Can't be found," or some such thing.
How to get rid of this pesky bugger?

I was able to delete the Task via the REST API:
$Credential = Get-Credential
$Headers = #{ "Accept" = "application/json; api-version=2.0"; "X-TFS-FedAuthRedirect" = "Suppress" }
$Uri = "http://hostname:8080/tfs/_apis/distributedtask/tasks/122d5ad0-61a1-11e6-b9c1-5b12bd371fa9"
Invoke-RestMethod -Credential $Credential -Headers $Headers -Uri $Uri -Method Delete
Following on Jesse Houwing's suggestion, my theory is that because it was created with the API in the first place (my recollection in my comment above is incorrect), it also had to be deleted with the API.

Related

using msmtp to send mail via php in docker container does NOT work in all cases

I am having issue making msmtp work in all cases when using php mail function. This is used in a docker container that relay's it to another docker container. It works in some cases but fails in others. See the php code for examples of when it fails/works.
msmtp version 1.8.22
Platform: x86_64-pc-linux-gnu
msmtprc config
host postfix
remove_bcc_headers off
allow_from_override off (When OFF breaks both mail functions)
PHP CODE: I need both cases to work at once
<?php
$to = "me#chrismuench.com";
$subject = "My subject";
$txt = "Hello world!";
$from = 'chris#phppointofsale.com';
$headers = "From: $from";
//1. Works with allow_overide_from on
//2. I get error when allow_overide_from off msmtp: account default from /usr/local/etc/msmtprc: envelope-from address is missing
mail($to,$subject,$txt,$headers);
//Never works in either case (The php library I use does this and I do NOT want to modify core). (same error message with on/off for allow_overide_from)
//Error msmtp: cannot use both --from and --read-envelope-from
mail($to, $subject, $txt, $headers, '-f '.$from);
?>

How to debug PowerShell process whithout error message or exception

I am trying to run the following PowerShell script from within my .NET application:
try {
Start-Process "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" -ArgumentList "--headless --disable-gpu --print-to-pdf=c:\myDir\file.pdf https://www.bing.com"
$x = "Complete"
$x | Out-File C:\myDir\error.txt
}
Catch {
$_ | Out-File C:\myDir\error.txt
}
Simply, the above will create a pdf based upon bing.com website
In my dev environment it runs fine as a PowerShell script. It also runs fine on the production server (again, as a PowerShell script).
The issue occurs when I invoke this PowerShell script from my web app on the production server. My C# code is
var command = "c:\myDir\ps.ps1";
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "powershell.exe";
psi.Arguments = command;
Process process = new Process();
process.StartInfo = psi;
process.Start();
This works fine on my dev machine. It fails on the production server. The error.txt file is written to disc which suggests it's not a permissions issue. However, the content of the error.txt file always shows "complete". It never errors.
So, it appears that the catch in the PowerShell script is never being hit. As such, no error message. There is no exception thrown in the C# code. Regardless, it isn't working.
How can I debug this?
Or, if easier, I'm happy to run the code directly instead of invoking the PowerShell script file but the following also does 'nothing'.
var command = $"\"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe\" -ArgumentList \"--no-sandbox --headless --disable-gpu --print-to-pdf={imagePath} {fullUrl}";
I was able to reproduce your problem. It is caused by the fact that web application on your production server is running under the user that is not currently logged in. It is running under identity of assigned application pool. Chrome has known issue of not working correctly if it's launched under the user different from currently logged user. If you check that link, you will see that issue was registered in December 2012 and still is not resolved. You could easily reproduce the problem if launch Chrome under the different user ("Run as different user" in shortcut context menu when called with pressed Shift). In this case Chrome will not open any page and will just show gray screen.
The workaround is to launch Chrome with --no-sandbox switch. Google actually does not recomment this. However if you run Chrome in automated way to access trusted source, I believe it's ok.
So to fix the problem modify start-process in the script in the following way:
start-process "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" -ArgumentList "--no-sandbox --headless --disable-gpu --print-to-pdf=c:\myDir\file.pdf https://www.bing.com"
UPDATE
I have underestimated the problem at first. Now after additional research and many tried approaches I can propose solution that works.
I didn't manage to fix your current approach of direct launch of powershell and chrome from Web Application. Chrome just fails to start and following errors appear in Event log:
Faulting application name: chrome.exe, version: 64.0.3282.186, time stamp: 0x5a8e38d5
Faulting module name: chrome_elf.dll, version: 64.0.3282.186, time stamp: 0x5a8e1e3d
Exception code: 0x80000003
Fault offset: 0x00000000000309b9
Faulting process id: 0x11524
Faulting application start time: 0x01d3bab1a89e3b4f
Faulting application path: C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
Faulting module path: C:\Program Files (x86)\Google\Chrome\Application\64.0.3282.186\chrome_elf.dll
Report Id: e70a5a36-26a4-11e8-ac26-b8ca3a94ba80
This error occurrs even if you configure application pool to use identity of some existing (ordinary) user that could launch the chrome.
May be it's possible to configure IIS or application pool to prevent these errors but I have not found the way.
My proposal is to switch from starting powershell process from controller action to scheduling a task with Windows task scheduler.
Here are the steps that should be taken to accomplish this task:
On your production server create a user under which the Chrome will be started. I'll refer to created user as 'testuser'.
Login under testuser, start chrome, open some site. Without this step, the flow was not successfully, probably because of missing chrome user account.
Grant "Log on as a batch job" right for testuser. This step is required for successfull execution of scheduled tasks under testuser. The procedure is described in this answer
Add --no-sandbox argument to the script as I described in my initial answer.
Replace the code of Process.Start() with scheduling of the task job.
The easiest way to schedule a task from .Net is via TaskScheduler NuGet. Install it to your application and add following code:
string powerShellScript = #"c:\myDir\ps.ps1";
string userName = #"YOURCOMP\testuser";
string userPassword = "TestPwd123";
using (TaskService ts = new TaskService())
{
TaskDefinition td = ts.NewTask();
td.Triggers.Add(new RegistrationTrigger
{
StartBoundary = DateTime.Now,
EndBoundary = DateTime.Now.AddMinutes(1),
});
td.Settings.DeleteExpiredTaskAfter = TimeSpan.FromSeconds(5);
td.Actions.Add(new ExecAction("powershell.exe", powerShellScript));
ts.RootFolder.RegisterTaskDefinition($#"Print Pdf - {Guid.NewGuid()}", td, createType: TaskCreation.Create, userId: userName, password: userPassword, logonType: TaskLogonType.Password);
}
In above code snippet change the name and password for testuser.
With this approach your script is successfully executed and pdf is printed successfully.
Update by OP
If the above continues to fail, then again, check the Event Viewer logs. In this case, I had an issues with a message similar to The machine-default permission settings do not grant Local Activation permission for the COM Server application with CLSID {20FD4E26-8E0F-4F73-A0E0-F27B8C57BE6F} and APPID Unavailable but it was resolved by granting permissions for the CLSID. Further, try to run the task in task scheduler by itself, such as create a new task to simply launch notepad or similar to make sure that this is working with the account you want to test. In my case, I had to use the administrator account.
I think additional to what CodeFuller said having no sandbox with --no-sandbox option, you should also disable all extensions, sync and bookmarks.
The best is having a Guest session alias "browse without sign-in" with--bwsi option.
What is funny is that during testing I have found out that it is better, got better pdf printout, to disable extensions explicitly with --disable-extensions before doing --bwsi.
I have tested it and for me it works. I'm looking forward for your feedback.
Edit1 and Edit3 - removing try...catch and adding user & password and adding psuser specifics
You are probably on domain so I have adjusting the script to run as different user on domain (the user must have correct rights!)
First create your credentials file with:
Login to user e.g. psuser
Create the password file:
# Encrypt user password and save it to file
Read-Host -AsSecureString | ConvertFrom-SecureString | Out-File 'C:\<your_path>\your_secret_password.txt'
Then run the below improved script with encrypted credentials:
$username = 'psuser' # This needs to be adjusted to correct user you are using
$domain = <your_domain> # adjust to your needs
$encrypted_passwd = get-content 'C:\<your_path>\your_secret_password.txt' | ConvertTo-securestring
# Setting process invocation parameters.
$process_start_info = New-Object -TypeName System.Diagnostics.ProcessStartInfo
$process_start_info.CreateNoWindow = $true
$process_start_info.UseShellExecute = $false
$process_start_info.RedirectStandardOutput = $true
$process_start_info.RedirectStandardError = $true
$process_start_info.UserName = $username
$process_start_info.Domain = $domain
$process_start_info.Password = $encrypted_passwd
$process_start_info.Verb = 'runas'
$process_start_info.FileName = 'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'
$process_start_info.Arguments = '--no-sandbox --disable-extensions --bwsi --headless --disable-gpu --print-to-pdf=C:\prg\PowerShell\test\chrome_file.pdf https://www.bing.com'
# Creating process object.
$process = New-Object -TypeName System.Diagnostics.Process
$process.StartInfo = $process_start_info
# Start the process
[Void]$process.Start()
$process.WaitForExit()
# synchronous output - captures everything
$output = $process.StandardOutput.ReadToEnd()
$output += $process.StandardError.ReadToEnd()
Write-Output $output
During the script debugging I have encountered these errors:
a) When you want to validate against a AD server but it is not available:
Exception calling "Start" with "0" argument(s): "There are currently no logon servers available to service the logon request"
At C:\prg\PowerShell\test\chrome_print.ps1:56 char:12
+ [Void]$process.Start()
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : Win32Exception
Exception calling "WaitForExit" with "0" argument(s): "No process is associated with this object."
At C:\prg\PowerShell\test\chrome_print.ps1:58 char:12
+ $process.WaitForExit()
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : InvalidOperationException
You cannot call a method on a null-valued expression.
At C:\prg\PowerShell\test\chrome_print.ps1:61 char:12
+ $output = $process.StandardOutput.ReadToEnd()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
You cannot call a method on a null-valued expression.
At C:\prg\PowerShell\test\chrome_print.ps1:62 char:12
+ $output += $process.StandardError.ReadToEnd()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
b) Missing domain information in the script:
Exception calling "Start" with "0" argument(s): "The stub received bad data"
At C:\prg\PowerShell\test\chrome_print.ps1:39 char:12
+ [Void]$process.Start()
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : Win32Exception
Exception calling "WaitForExit" with "0" argument(s): "No process is associated with this object."
At C:\prg\PowerShell\test\chrome_print.ps1:41 char:12
+ $process.WaitForExit()
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : InvalidOperationException
You cannot call a method on a null-valued expression.
At C:\prg\PowerShell\test\chrome_print.ps1:44 char:12
+ $output = $process.StandardOutput.ReadToEnd()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
You cannot call a method on a null-valued expression.
At C:\prg\PowerShell\test\chrome_print.ps1:45 char:12
+ $output += $process.StandardError.ReadToEnd()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Prints the pdf
and the stderr messages:
[0313/112937.660:ERROR:gpu_process_transport_factory.cc(1009)] Lost UI shared context.
[0313/112937.662:ERROR:instance.cc(49)] Unable to locate service manifest for metrics
[0313/112937.662:ERROR:service_manager.cc(890)] Failed to resolve service name: metrics
[0313/112938.152:ERROR:instance.cc(49)] Unable to locate service manifest for metrics
[0313/112938.153:ERROR:service_manager.cc(890)] Failed to resolve service name: metrics
[0313/112942.876:INFO:headless_shell.cc(566)] Written to file C:\prg\PowerShell\test\chrom e_file.pdf.
Edit2 Adding windows account impersonation with ASP.NET
Impersonate a windows account with ASP.NET:
ASP.NET user is not passed into the new threads (by default). When you want to invoke PowerShell script it is invoked in other thread with different credentials (you can overcome that with above script when you have a dedicated domain authenticated user for running the above script). By default the script is executed under build-in account NT AUTHORITY\NETWORK SERVICE.
These steps are to overcome it on ASP.NET level:
1) Enable Windows Authentication in IIS
a) Install it first (this is windows 2008 R2 screenshot):
b) enable it on your IIS:
Change it to enabled:
2) Change your site's web.config to correctly handle impersonation
Edit the web.config file in your site’s directory. In order to execute the server side code of the current user's security context (AD).
Find the xml tag: <system.web> and add two new elements to enable the windows authentication
<authentication mode="Windows" />
<identity impersonate="True" />
3) To correctly write code to invoke in-process PowerShell script
You need to adjust your ASP.NET code in a way that you will have powershell Runspace and you will invoke the script inside the Runspace in a pipeline
A quick example:
// You need to create a Runspace. Each other pipeline you create will run in the same Runspace
// Do it only once, all others will be pipelined
RunspaceConfiguration powershellConfiguration = RunspaceConfiguration.Create();
var powershellRunspace = RunspaceFactory.CreateRunspace(powershellConfiguration);
powershellRunspace.Open();
// create a pipeline the cmdlet invocation
using ( Pipeline psPipeline = powershellRunspace.CreatePipeline() ){
// Define the command to be executed in this pipeline
Command script = new Command("PowerShell_script");
// Add any parameter(s) to the command
script.Parameters.Add("Param1", "Param1Value");
// Add it to the pipeline
psPipeline.Commands.Add(script);
try {
// Invoke() the script
var results = psPipeline.Invoke();
// work with the results
} catch (CmdletInvocationException exception) {
// Any exceptions here - for the invoked process
}
}
4) Modify aspnet.config to allow impersonation to cross threads
This step allows you to run as your current, impersonated, user.
You have to modify your servers’s aspnet.config file.
Add two xml elements to the configuration and runtime:
<configuration>
<runtime>
...
<legacyImpersonationPolicy enabled="true" />
<alwaysFlowImpersonationPolicy enabled="false" />
</runtime>
</configuration>
You have to redirect the stdin and stdout so that it sends it from powershell.exe back to the parent process (your web app). I modified your code sample to do this:
var command = "c:\myDir\ps.ps1";
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "powershell.exe";
psi.Arguments = command;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
Process process = new Process();
process.StartInfo = psi;
process.Start();
process.WaitForExit();
Console.WriteLine(process.StandardOutput);
Console.WriteLine(process.StandardError);

Jupyter: XSRF cookie does not match POST

I am trying to transfert files using a python program running on a local Anaconda to a local Jupyter within a docker container using the Jupyter rest API.
I managed already to execute a requests.get() succesfully after muddling-through a bit on how to input the token.
Now I would like now to execute a requests.post() command to transfert the files.
Configuration:
local docker container running on docker toolbox for windows
docker version 17.04.0-ce, build 4845c56
tensorflow/tensorflow incl. Jupyter latest version install
jupyter_kernel_gateway==0.3.1
local Anaconda v. 4.3.14 running on a windows 10 machine
Code:
token = token_code_provided_by_jupyter_at_startup
api_url = "http://192.168.99.100:8888/api/contents"
# getting the file's data from disk and converting into a json file
cwd = os.getcwd()
file_location = cwd+r'\Resources\Test\test_post.py'
payload = open(file_location, 'r').read()
b64payload = base64.encodestring(payload)
body = json.dumps({
'content':b64payload,
'name': 'test_post.py',
'path': '/api/contents/',
'format': 'base64',
'type':'file'
})
# getting the xsrf cookie
client = requests.session()
client.get('http://192.168.99.100:8888/')
csrftoken = client.cookies['_xsrf']
headers ={'Content-type': 'application/json', 'X-CSRFToken':csrftoken, 'Referer':'http://192.168.99.100:8888/api/contents', 'token':token}
response = requests.post(api_url, data=body, headers=headers, verify=True)
Error returned
[W 12:22:36.710 NotebookApp] 403 POST /api/contents (192.168.99.1): XSRF cookie does not match POST argument
[W 12:22:36.713 NotebookApp] 403 POST /api/contents (192.168.99.1) 4.17ms referer=http://192.168.99.100:8888/api/contents
My solution is inspired by #SaintNazaire. In my Chrome browser, I opened the cookie folder and found the repeated _xsrf items in Cookies. I removed all of them and refreshed the Jupyter, and then everything went well.
Actually there is no need for xsrf cookie when using header token for authentification.
headers = {'Authorization': 'token ' + token}
Reference is made to the Jupyter notebook documentation.
http://jupyter-notebook.readthedocs.io/en/latest/security.html

Microsoft.TeamFoundation.VersionControl.Client.ItemNotMappedException even when the workspace exists and has a mapping

Using TFS 2015 update 2, an agent was installed in a machine, the agent creates its workspace:
Some custom MSBuild tasks developed InHouse were implemented in the build definition that will run on the agent. Those tasks perform some operations against the TFS server.
When the build definition is queued for a new build here is what I got:
In the build machine I proceed to run the following script, in order to verify the existence of the workspace :
# Script to find a Team Foundation workspace
param(
[string] $workspaceHint = $(get-location).Path
)
begin
{
# load the needed client dll's
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Client")
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.VersionControl.Client")
# fetches a Workspace instance matching the WorkspaceInfo found in the cache file
function getWorkspaceFromWorkspaceInfo($wsInfo)
{
$tfs = [Microsoft.TeamFoundation.Client.TeamFoundationServerFactory]::GetServer($wsInfo.ServerUri.AbsoluteUri)
$vcs = $tfs.GetService([Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer])
$vcs.GetWorkspace($wsInfo)
# TODO: likely add some convenience properties/methods for easier scripting support
}
}
process
{
# is there only 1 workspace in our cache file? If so, use that one regardless of the hint
$workspaceInfos = [Microsoft.TeamFoundation.VersionControl.Client.Workstation]::Current.GetAllLocalWorkspaceInfo()
if ($workspaceInfos.Length -eq 1)
{
return getWorkspaceFromWorkspaceInfo($workspaceInfos[0])
}
if (test-path $workspaceHint)
{
# workspace hint is a local path, get potential matches based on path
$workspaceInfos = [Microsoft.TeamFoundation.VersionControl.Client.Workstation]::Current.GetLocalWorkspaceInfoRecursively($workspaceHint)
}
else
{
# workspace hint is NOT a local path, get potential matches based on name
$workspaceInfos = #($workspaceInfos | ?{ $_.name -match $workspaceHint })
}
if ($workspaceInfos.Length -gt 1)
{
throw 'More than one workspace matches the workspace hint "{0}": {1}' -f
$workspaceHint, [string]::join(', ', #($workspaceInfos | %{ $_.Name}))
}
elseif ($workspaceInfos.Length -eq 1)
{
return getWorkspaceFromWorkspaceInfo($workspaceInfos[0])
}
else
{
throw "Could not figure out a workspace based on hint $workspaceHint"
}
}
The script is not able to find any workspace.
Then, the TFS 2015 Power tools were installed with its powershell cmdlets in the machine and run the following script:
if ( (Get-PSSnapin -Name Microsoft.TeamFoundation.PowerShell -ErrorAction SilentlyContinue) -eq $null )
{
Add-PSSnapin -Name Microsoft.TeamFoundation.PowerShell
}
$ws = Get-TfsWorkspace -Path C:\t\1\s
$ws.Folders
Showing the workspace and the items mapped.
Queuing new builds, keep showing the same error.
The workspace is a public server one, and following some ancient post in msdn forums, I clean the TFS cache in the machine.
Any clue how to make the Microsoft.TeamFoundation.VersionControl.Client be able to recognize the workspace?
I fixed the ItemNotMappedException problem on my machine by running something like the following PowerShell script;
$localReference = "C:\Repository\Project\Project.sln"
$teamProjectCollection="http://tfsserver:8080/tfs/projectcollection"
$username = $env:UserName
Add-type -AssemblyName "Microsoft.TeamFoundation.Client, Version=12.0.0.0, Culture=Neutral, PublicKeyToken=b03f5f7f11d50a3a"
Add-type -AssemblyName "Microsoft.TeamFoundation.Common, Version=12.0.0.0, Culture=Neutral, PublicKeyToken=b03f5f7f11d50a3a"
Add-type -AssemblyName "Microsoft.TeamFoundation.VersionControl.Client, Version=12.0.0.0, Culture=Neutral, PublicKeyToken=b03f5f7f11d50a3a"
Add-type -AssemblyName "Microsoft.TeamFoundation.VersionControl.Common, Version=12.0.0.0, Culture=Neutral, PublicKeyToken=b03f5f7f11d50a3a"
$folder = [System.IO.Path]::GetDirectoryName($localReference);
Push-Location $folder;
$tfsTeamProjectCollection = New-Object Microsoft.TeamFoundation.Client.TfsTeamProjectCollection($teamProjectCollection)
$versioncontrolServer = $tfsTeamProjectCollection.GetService([Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer])
[Microsoft.TeamFoundation.VersionControl.Client.Workstation]::Current.EnsureUpdateWorkspaceInfoCache($versionControlServer, $username);
$workspace = $versioncontrolServer.GetWorkspace($localReference)
echo $workspace
Pop-Location
You will need to change the initial variables to match your environment.
Hope it helps
Recently I ran into a similar issue where it was throwing the error saying "There is no working folder mapping for 'Mapped path'"
Tried using below command to get the workspace path.
tf workspaces /format:detailed /owner:UserName /collection:http://TFSurl:8080/tfs
Mapping seemed to be fine.
using Workstation.EnsureUpdateWorkspaceInfoCache worked with like a gem.
Use the following link for sample code:
How to call GetWorkspace in TFS properly?
Please add the Microsoft.TeamFoundation.Common assembly in your script and try again.
# load the needed client dll's
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Client")
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Common")
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.VersionControl.Client")

Connecting to Active Directory

I have the following script from a book. When I try to run this, I get nothing output to the screen.
$objADSI = [adsi]""
$domain = $objADSI.distinguishedname
$userContainer = [adsi]("LDAP://cn=users," + $domain)
foreach($child in $userContainer) {
Write-Host $child.samaccountname
}
If I echo $userContainer, I get:
distinguishedName : {CN=Users,DC=company,DC=co,DC=uk}
Path : LDAP://cn=users,DC=company,DC=co,DC=uk
Do I need to run winrm quickconfig on the Active Directory server? The Active Directory server is running Windows Server 2003 standard edition. Or am I getting nothing returned for some other reason?
Change your foreach like this:
foreach($child in $userContainer.children)

Resources