How to use AppCMD to test and see if a website exists in IIS7 using the Site's Name? - appcmd

I would like to add new bindings to a site using appcmd but I need to see if it exists first. How can I do so using AppCMD?
Much appreciated!

You can create a batch file with the following code :
#ECHO OFF
SET appcmd=CALL %WINDIR%\system32\inetsrv\appcmd
%appcmd% list site /name:"Default Web Site"
IF "%ERRORLEVEL%" EQU "0" (
ECHO EXISTS
REM Add your bindings here
) ELSE (
ECHO NOT EXISTS
)

Here's the PowerShell way:
$exists = (&$appcmd list apppool /name:'MyApplicationPool') -ne $null
if ($exists -eq $false)
{
Write-Host 'App Pool does not exist'
}
else
{
Write-Host 'App Pool exists'
}

You can specify the site.name and do that in one line with the command line : "%systemroot%\system32\inetsrv\AppCmd.exe" list apps /path:"/PORTALSiteName" /site.name:"Default Web Site" && ECHO EXISTS

Related

Creating registry DWORD entry with PowerShell

I am trying to create registry entries for some time now.
Enviroment:
Offline environment (No Domain)
1 Windows Server 2012 R2
200 Windows 7 clients
The following entry should be created on several computers:
[HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\system]
"LocalAccountTokenFilterPolicy"=dword:00000001
For this I would like to use the following script
$Computers = Get-Content "C:\Scripts\Clients.txt"
$Path = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
$Name = "LocalAccountTokenFilterPolicy"
$PropertyType = "DWord"
$Value = 1
$results = foreach ($computer in $Computers) {
if (Test-Connection -ComputerName $computer -Count 1 -Quiet) {
try {
Set-ItemProperty -Path $path -Name $Name -Value $Value -Type $PropertyType -ErrorAction 'Stop'
$status = "Success"
} catch {
$status = "Failed"
}
} else {
$status = "Unreachable"
}
New-Object -TypeName PSObject -Property #{
'Computer' = $computer
'Status' = $status
}
}
$results | Export-Csv -NoTypeInformation -Path "./error.csv"
The script is executed, no error appears, but the entries were not created.
Where is my error?
Always try a simple 'Get' first, and then progress to testing lines before trying your 'Set'...
So you first test locally on a system, before your foreach invoke, on single system:
`Get-ItemProperty HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -Name LocalAccountTokenFilterPolicy`
If you get a good response like this:
LocalAccountTokenFilterPolicy : 0
PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Curre
ntVersion\Policies\System
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Curre
ntVersion\Policies
PSChildName : System
PSDrive : HKLM
PSProvider : Microsoft.PowerShell.Core\Registry
Then you've got the right command to work with. Now change the 'Get' to a 'Set' and work out the values LOCALLY.
I think you are close, but missed something in your tests...
Do ONE at a time, locally, first in PowerShell ISE. Then invoke-command to that same single system, then one by one add your tests...
- Patrick Burwell, 25 year Windows and Linux SysAdmin

TFS 2015 build vNext update file version with commit id

Do you know how inject commit id into file version, so every assembly would heve version like 2.0.6565.0 where 6565 is related to C6565commit ID in TFS ?
It looks some power shell script is needed.
If your question is similar to your another post TFS 2015. the $(var.SourceLocation) variable is not available at gated-check in, that want to get the changeset id that hasn't checked in during gated check-in, then it's impossible in a single build.
If you don't use gated check in, then you can use $Env:BUILD_SOURCEVERSION in a powershell script to set the AssemblyVersion. Here is already a script at the website below, you can refer to it:
https://github.com/wulfland/ScriptRepository/blob/master/TFSBuild/TFSBuild/AssemblyVersion/Set-AssemblyVersion/Set-AssemblyVersion.ps1
Finally I created my own PS script based on this post.
The idea update version in all files with assembly info
$CommitId = ([string]$env:BUILD_SOURCEVERSION) -replace "[^0-9]+", ""
$AllVersionFiles = Get-ChildItem $SourceDir AssemblyInfo.cs -recurse
$regexToFindVersion = "Version\(""([0-9]+)\.([0-9]+).+"""
foreach ($file in $AllVersionFiles)
{
Write-Host "Processing " $file.FullName
(Get-Content $file.FullName) |
%{$_ -replace $regexToFindVersion, ('Version("$1.$2.0.' + $CommitId + '"') } |
Set-Content $file.FullName -Force
}
Full script can be found here.
The script must be placed before building project:

TFS: How to validate if every file is checked-in?

We are working on several ASP.NET MVC C# projects within Visual Studio 2015 and Team Foundation Server 2013. Sometimes the NuGet upgrade process is a mess and some of the replaced files (mostly *.png, *.gif, *.ttf) have not been checked-in properly.
What we have figured out so far: the check-in process gets into trouble, if directories should be removed and created in one step. You have to check-in twice. The problem is, if you don’t know about this and one of our developers retrieves the latest source, there are missing files. Visual Studio indicates that with a warning icon in Solution Explorer.
My question is: Is it possible to validate, if every file is present during gated-checkin or nightly-build on TFS which is linked in the csproj file? At least there should be a warning during build.
Hint: This is only a problem with files, which are not compiled (*.cs files) or do not have the setting “copy during build into output directory”. This happens e.g. with JS-files, which are bundled.
Final solution:
Write-Host "Check availability for all referenced files in all projects ..."
function Check-Files($directory, $files){
if (!$directory.EndsWith("/")) { $directory = "$($directory)/" }
ForEach($file in $files){
if($file){
Write-Host " Referenced file $($directory)$file"
if(-not (Test-Path "$($directory)$($file)")){
throw [System.IO.FileNotFoundException] "$($directory)$($file) not found."
}
}
}
}
function CheckProjectFile($csprojFile){
[xml]$projectContent = Get-Content $csprojFile
Write-Host "Checking project: $($csprojFile) ..."
$directory = Split-Path $csprojFile
ForEach($itemGroup in $projectContent.Project.ItemGroup){
Check-Files -files $itemGroup.Reference.HintPath -dir $directory
Check-Files -files $itemGroup.Compile.Include -dir $directory
Check-Files -files $itemGroup.None.Include -dir $directory
Check-Files -files $itemGroup.Content.Include -dir $directory
Check-Files -files $itemGroup.TypeScriptCompile.Include -dir $directory
Check-Files -files $itemGroup.ProjectReference.Include -dir $directory
}
}
$csprojFiles = Get-ChildItem -Path ./ -Recurse *.csproj | Select-Object -Property FullName
ForEach($file in $csprojFiles){
CheckProjectFile($file.FullName)
}
I added the script file to my Team Project on TFS, changed my build definition, added the script directory to my "Source Settings" and included the script into "Pre-build script path". Done!
I created a small piece of powershell that you can execute as a step before building the solution.
function Check-Files($files){
ForEach($file in $files){
if($file){
Write-Host "looking for $file"
if(-not (Test-Path $file)){
throw [System.IO.FileNotFoundException] "$file not found."
}
}
}
}
[xml]$projectContent = Get-Content ./your.csproj
ForEach($itemGroup in $projectContent.Project.ItemGroup){
Check-Files -files $itemGroup.Reference.HintPath
Check-Files -files $itemGroup.Compile.Include
Check-Files -files $itemGroup.None.Include
Check-Files -files $itemGroup.Content.Include
Check-Files -files $itemGroup.TypeScriptCompile.Include
Check-Files -files $itemGroup.ProjectReference.Include
}
Hope this helps you.
Kind regards
Jan
First of all, make sure you check in the whole solution/project every time. In this way, all the edit files in this solution/ project will list in the Included pending changes. If you only check in a single file, then other edits will list in Excluded changes and won't be checked in.
Also you can use check-in policy to prevent check-in without a review. Here's an existing check-in policy that requires code review before check-in:
https://visualstudiogallery.msdn.microsoft.com/c476b708-77a8-4065-b9d0-919ab688f078

Powershell send mail

I am having the following problem.
I have a powershell script to send me emails with log files attached.
The only problem is that I need only the log files that are not empty.
So i have tried to use this script:
If ((Get-content "Log.txt") -gt 0 ) {
$smtp.Send($msg)
echo "email sent"
} else {
echo "File is blank"
}
It seems that -gt 0 is not working for me.
No matter what I have tried powershell still sends me the empty logs.
So can you please show me where I am wrong?
I have tried this as well:
If ((Get-Content $file) -eq $Null) {
"File is blank"
} else {
$smtp.Send($msg)
echo "email sent"
}
But it is still not working.
Thank you in advance.
Get-Content will read the entire contents of the file - only to throw it all away! That's a huge waste of resources.
Instead, get info from the fileystem itself about the file with get-item or get-childitem.
if ((get-item "log.txt").length -gt 0) {
do stuff
}
It also looks like you're using an antiquated method of sending email. In PowerShell 2.0 and above, use Send-MailMessage - it's much easier to use. In fact, if you have all the logfiles in one directory, you can distill this to a two-liner:
$logs = get-childitem -path PATH_TO_LOGS|where-object{($_.length -gt 0) -and !$_.PSIsContainer}|select-object -expandproperty fullname
Send-Mailmessage -attachments $logs OTHER_PARAMETERS_HERE

How can I use PowerShell to update build qualities on previous TFS Builds?

We are using TFSDeployer to listen to build quality changes and deploy to our staging environment when it transitions to "Staging".
I'd like to have it go ahead and update all of the other builds that have a currently build quality of "Staging" to be "Rejected".
This appears to be something that needs to happen inside the PowerShell script which looks like:
$droplocation = $TfsDeployerBuildData.DropLocation
ECHO $droplocation
$websourcepath = $droplocation + "\Release\_PublishedWebsites\CS.Public.WebApplication\"
$webdestinationpath = "\\vmwebstg\WebRoot\CreditSolutions\"
new-item -force -path $webdestinationpath -itemtype "directory"
get-childitem $webdestinationpath | remove-item -force -recurse
get-childitem $websourcepath | copy-item -force -recurse -destination $webdestinationpath
$configFile = $webdestinationpath + "web.development.config"
remove-item $configFile -force
$configFile = $webdestinationpath + "web.staging.config"
$configFileDest = $webdestinationpath + "web.config"
move-item $configFile $configFileDest -force
So, how can I do this?
First add the Get-tfs function to your script:
function get-tfs (
[string] $serverName = $(Throw 'serverName is required')
)
{
# load the required dll
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Client")
$propertiesToAdd = (
('VCS', 'Microsoft.TeamFoundation.VersionControl.Client', 'Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer'),
('WIT', 'Microsoft.TeamFoundation.WorkItemTracking.Client', 'Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemStore'),
('BS', 'Microsoft.TeamFoundation.Build.Common', 'Microsoft.TeamFoundation.Build.Proxy.BuildStore'),
('CSS', 'Microsoft.TeamFoundation', 'Microsoft.TeamFoundation.Server.ICommonStructureService'),
('GSS', 'Microsoft.TeamFoundation', 'Microsoft.TeamFoundation.Server.IGroupSecurityService')
)
# fetch the TFS instance, but add some useful properties to make life easier
# Make sure to "promote" it to a psobject now to make later modification easier
[psobject] $tfs = [Microsoft.TeamFoundation.Client.TeamFoundationServerFactory]::GetServer($serverName)
foreach ($entry in $propertiesToAdd) {
$scriptBlock = '
[System.Reflection.Assembly]::LoadWithPartialName("{0}") > $null
$this.GetService([{1}])
' -f $entry[1],$entry[2]
$tfs | add-member scriptproperty $entry[0] $ExecutionContext.InvokeCommand.NewScriptBlock($scriptBlock)
}
return $tfs
}
Next, instantiate the TFS object
$tfs = get-tfs http://YourTfsServer:8080
Then find the builds with a build quality of "Staging"
$builds = $tfs.BS.GetListOfBuilds("Test Project", "TestBuild") |
where {$_.BuildQuality -eq "Staging"}
Finally, update the quality of these builds
foreach ($build in $builds) { $tfs.BS.UpdateBuildQuality($build.BuildUri, "Rejected") }
(I haven't run this script yet, but you should be able to get it going without troubles)
More info on my blog: Using the Team Foundation Object Model with PowerShell
One last advice, if you update the Build quality from within the script that is running from TfsDeployer, you could end up with 2 script running at the same time if you have a mapping for the Staging --> Rejected transition!
This is not the full answer as I don't have much knowledge of TFSDeployer or indeed PowerScript. However the .NET API for Team Build is able to do this. You want to get hold of the IBuildDetail for the build. The easiest way to get this is if you have the BuildUri (which it sounds like you might) in which case a call to IBuildServer.GetBuild should get you the build you are interested in.
IBuildServer also has the QueryBuilds methods which you would be able to call to find the builds that are of interest to you, you would then set the Quality property on the IBuildDetails that you wanted to change, remembering to call the Save() method on each one.
Hope that gives you a start - sorry it isn't a more complete answer.

Resources