• MSBuild is not a scripting tool. Even it looks like it can do various “tasks” with it, you have to keep in mind it is not for scripting purpose, generally speaking.
  • Each task will only be executed once. Even you try to call it multiple times, MSBuild will check its conditions and will not do it again if all condition are the same. The conditions include input and output properties. So to get around it, you can specify different inputs/outputs.
  • The parameters you passed in through “/p:parametername=parametervalue” will become global variables and hard to change (i.e. OutDir)
  • You can import target or property(.props) files to do your customization including defining tasks, item and property groups
  • For iteration (looping) through a list, use “%”


     <DefaultWebDir Include="$(OutDir)_PublishedWebsites\$(MSBuildProjectName)\**\*.*" />
    <MyWeb Include="MyProjectName">
     <WebNewName Condition="$(MSBuildProjectName)==%(MyWeb.Identity)">%(NewName)</WebNewName>
     Condition="$(MSBuildProjectName)==%(MyWeb.Identity) And $(WebNewName)!=''" >
  • For array type of list, you use ItemGroup
  • In this example, \**\*.* means all files under current and all subfolders will be included in this DefaultWebDir ItemGroup
  • To access the ItemGroup, use @(DefaultWebDir), MSBuild will loop through it for you
  • MyWeb is another array/ItemGroup where I define some custom attributes so I can compare them against current project name and assign a new folder name. This way, I can easily give the target folder a new name other than the VS project name. Actually, once I take those ItemGroup definition to a separate props file, it will become a configurable build mapping processes.
  • Then for the Copy task, %(MyWeb) will tell MSBuild to loop through the item group thus copy all items if the condition meets
  • %(MyWeb.Identity) is the build-in attribute to get the item
  • %(NewName) to access my custom attribute
  • “-> is a MSBuild build-in transformation which can help us easily specify the difference between source and target path
  • %(RecursiveDir)
  • %(Filename)
  • %(Entension)