https://sedodream.com/images/zenicon.jpgSayed's bloghttps://sedodream.com/Sayed Ibrahim Hashimi's blog, discussing MSBuild and .NET.https://sedodream.com/images/zenicon.jpgSayed's bloghttps://sedodream.com/Sayed Ibrahim HashimiFri, 20 Feb 2015 18:04:28 GMTsayed.hashimi@gmail.comsayed.hashimi@gmail.comhttps://sedodream.com/feed/trackback/976a6435-338a-4cde-9a82-11130523c8a1https://sedodream.com/feed/pingbackhttps://sedodream.com/post/976a6435-338a-4cde-9a82-11130523c8a1https://sedodream.com/2015/02/20/visual-studio-web-packages-fixing-the-path-in-the-generated-web-package/comments#comments-starthttps://sedodream.com/feed/rss/comments/976a6435-338a-4cde-9a82-11130523c8a1Visual Studio Web Packages fixing the path in the generated web packagehttps://sedodream.com/post/976a6435-338a-4cde-9a82-11130523c8a1https://sedodream.com/2015/02/20/visual-studio-web-packages-fixing-the-path-in-the-generated-web-packageFri, 20 Feb 2015 18:04:28 GMT<div><p>If you’ve ever created an MSDeploy web package using Visual Studio you may have noticed that the generated package has the folder structure of where the application was packaged. Since MSDeploy parameters are used when installing the package in most cases the structure of the web package doesn’t matter. In some cases this causes problems and it would be desired to have a flatter package structure.</p> <p>Today on twitter <a href="https://twitter.com/ashic">@ashic</a> contacted me asking basically “How can I update the package folder structure without modifying the project?” OK it’s possible, but I’ll first explain how you can easily solve this problem in a few ways and then move on to his actual question.</p> <p>Option 1: Add the PackageWeb NuGet package</p> <p>The easiest way to fix this problem is to add a the <a href="http://www.nuget.org/packages/PackageWeb/">PackageWeb NuGet package</a> into your project (that’s a package that I’ve authored you can see the <a href="https://github.com/sayedihashimi/package-web/">sources here</a>). This will update the path to a flat structure and add a .ps1 file when creating the package. You can ignore the .ps1 file if you like.</p> <p>Option 2: Add package.wpp.targets to your project</p> <p>In web projects when you build it will import any files in the same folder as the .csproj/.vbproj file matching the following file pattern *.wpp.targets. To fix the issue drop the following contents in to that file. Note: you can find the latest version of this <a href="https://gist.github.com/sayedihashimi/2c4ce6e492e2eda5fc9c">in this gist</a>.</p><pre class="brush: bash;">&lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt; &lt;PropertyGroup&gt; &lt;PackagePath Condition=" '$(PackagePath)'=='' "&gt;website&lt;/PackagePath&gt; &lt;EnableAddReplaceToUpdatePacakgePath Condition=" '$(EnableAddReplaceToUpdatePacakgePath)'=='' "&gt;true&lt;/EnableAddReplaceToUpdatePacakgePath&gt; &lt;PackageDependsOn&gt; $(PackageDependsOn); AddReplaceRuleForAppPath; &lt;/PackageDependsOn&gt; &lt;/PropertyGroup&gt; &lt;Target Name="AddReplaceRuleForAppPath" Condition=" '$(EnableAddReplaceToUpdatePacakgePath)'=='true' "&gt; &lt;PropertyGroup&gt; &lt;_PkgPathFull Condition=" '$(WPPAllFilesInSingleFolder)'!='' "&gt;$([System.IO.Path]::GetFullPath($(WPPAllFilesInSingleFolder)))&lt;/_PkgPathFull&gt; &lt;_PkgPathFull Condition=" '$(_PkgPathFull)' == '' "&gt;$([System.IO.Path]::GetFullPath($(_PackageTempDir)))&lt;/_PkgPathFull&gt; &lt;/PropertyGroup&gt; &lt;!-- escape the text into a regex --&gt; &lt;EscapeTextForRegularExpressions Text="$(_PkgPathFull)"&gt; &lt;Output TaskParameter="Result" PropertyName="_PkgPathRegex" /&gt; &lt;/EscapeTextForRegularExpressions&gt; &lt;ItemGroup&gt; &lt;MsDeployReplaceRules Include="replaceFullPath"&gt; &lt;Match&gt;$(_PkgPathRegex)&lt;/Match&gt; &lt;Replace&gt;$(PackagePath)&lt;/Replace&gt; &lt;/MsDeployReplaceRules&gt; &lt;/ItemGroup&gt; &lt;/Target&gt; &lt;/Project&gt; </pre> <p>Then when you build this project the package path will be consist of Content\website and all content files are under that.</p> <p>Now on to his question, <strong>“How can I update the package path for a project without modifying the project/project files when building from the command line”"?”</strong></p> <p>Now that we have the MSBuild .targets file to do the work for us the only thing we need to figure out is how to add this .targets file into the build process when calling msbuild.exe myproject.csproj /t:Package. It’s pretty easy actually. You can take the <a href="https://gist.github.com/sayedihashimi/2c4ce6e492e2eda5fc9c">package.wpp.targets</a> file and drop it in a well known location (let’s say c:\msbuild\package.targets for this example). Then when you build your project you can pass a property to get that file imported. The command is below.</p><pre class="brush: bash;">msbuild myproject.csproj /t:Package /p:CustomAfterMicrosoftCommonTargets=c:\msbuild\package.targets&nbsp; </pre> <p>In Microsoft.Common.targets (which is imported by most project types) contains a property CustomAfterMicrosoftCommonTargets which defaults to a folder under Program Files. You can override that value via MSBuild parameters to override it which is what we are doing here. Note: if you have a common targets file in the default shared location then this obviously will not work for you. You'd have to add another conditional import with a new property for that case.</p> <p>Thanks,</p> <p>Sayed Ibrahim Hashimi</p></div>https://sedodream.com/2015/02/20/visual-studio-web-packages-fixing-the-path-in-the-generated-web-package/comments#comments-starthttps://sedodream.com/feed/trackback/108e59b5-1467-43f0-a178-511195ac05b8https://sedodream.com/feed/pingbackhttps://sedodream.com/post/108e59b5-1467-43f0-a178-511195ac05b8https://sedodream.com/2015/01/03/how-to-get-msbuild-log-files-in-markdown-format/comments#comments-starthttps://sedodream.com/feed/rss/comments/108e59b5-1467-43f0-a178-511195ac05b8How to get MSBuild log files in Markdown formathttps://sedodream.com/post/108e59b5-1467-43f0-a178-511195ac05b8https://sedodream.com/2015/01/03/how-to-get-msbuild-log-files-in-markdown-formatSat, 03 Jan 2015 00:52:55 GMT<div><p>Have you ever wanted to view MSBuild log files in Markdown format? If you are using <a href="https://github.com/ligershark/psbuild">psbuild</a> then you’ll now get this feature for free if you upgrade your install. <a href="https://github.com/ligershark/psbuild">psbuild</a> is a PowerShell wrapper for msbuild.exe. You can learn more about it on the <a href="https://github.com/ligershark/psbuild">github page</a> or my <a href="http://sedodream.com/2014/07/19/IntroducingPSBuildAnImprovedInterfaceForMsbuildexeInPowerShell.aspx">previous blog post</a> on it.</p> <p>&nbsp;</p> <p>Using psbuild to build a project the basic command will look like the following.</p> <blockquote><pre class="brush: bash;">Invoke-MSBuild myprojectorsln.csproj </pre></blockquote> <p>After that to get the log you’ll invoke</p> <blockquote><pre class="brush: bash;">Open-PSBuildLog </pre></blockquote> <p>Open-PSBuildLog will open the log file from the last build executed by that instance of psbuild. The Open-PSBuildLog has a single parameter, format, which defines which log file to return. This parameter takes the following values.</p> <ul> <li>detailed <li>diagnostic <li>markdown</li></ul> <p>Detailed is the default format. So to get your log file in MSBuild format execute.</p> <blockquote><pre class="brush: bash;">Open-PSBuild markdown </pre></blockquote> <p>This will open the .md file in the default editor. Below is a screenshot of a sample log file.</p> <p><a href="/content/binary/Windows-Live-Writer/How-to-view-MSBuild-log-files-in-Markdow_EAF7/image_2.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="/content/binary/Windows-Live-Writer/How-to-view-MSBuild-log-files-in-Markdow_EAF7/image_thumb.png" width="1421" height="624"></a></p> <p>&nbsp;</p> <p>If you have any comments reach out to <a href="https://twitter.com/sayedihashimi">me on twitter</a> or <a href="https://github.com/ligershark/psbuild/issues">open an issue</a> in psbuild to discuss further.</p> <p>&nbsp;</p> <p>Sayed Ibrahim Hashimi | <a href="http://msbuildbook.com">http://msbuildbook.com</a> | <a href="https://twitter.com/sayedihashimi">@SayedIHashimi</a></p></div>https://sedodream.com/2015/01/03/how-to-get-msbuild-log-files-in-markdown-format/comments#comments-startMSBuildpsbuildhttps://sedodream.com/feed/trackback/0b21af16-02fe-4428-9cdb-893947f4877bhttps://sedodream.com/feed/pingbackhttps://sedodream.com/post/0b21af16-02fe-4428-9cdb-893947f4877bhttps://sedodream.com/2014/12/03/i-closed-my-bbvacompass-account-because-they-believe-that-hi123-is-a-strong-password/comments#comments-starthttps://sedodream.com/feed/rss/comments/0b21af16-02fe-4428-9cdb-893947f4877bI closed my BBVACompass account because they believe that “Hi123” is a strong passwordhttps://sedodream.com/post/0b21af16-02fe-4428-9cdb-893947f4877bhttps://sedodream.com/2014/12/03/i-closed-my-bbvacompass-account-because-they-believe-that-hi123-is-a-strong-passwordWed, 03 Dec 2014 07:03:57 GMT<div><p>OK, so this off topic, but its so important that I had to blog about this. Let me give you some background. Last week I was traveling with my family on a road trip to Canada. Usually I’m super paranoid and never connect to any open wireless network (I pay for an carry my own mi-fi device due to this). Since we were in Canada I didn’t want to get hit with so many charges so I chanced it on a few networks. I made sure to connect to VPN as soon as I could, but there was still some time that I was not completely protected. At one point I thought that my gmail account had been hacked (<em>further investigation proved this to be false thankfully</em>). So I connected to a known network, applied VPN, double checked that my IP was routed through VPN and started changing my critical passwords. One of those was an account with <a href="https://www.bbvacompass.com/">BBVACompass</a> bank. I initially setup this account a while back, and evidently I wasn’t as concerned with online security as I am now. </p> <p>When I got to the password reset screen here is the tooltip indicating the password requirements.</p> <p><a href="/content/binary/WindowsLiveWriter/IclosemyBBVACompassaccountbecausetheybel_13580/image_2.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; float: none; margin-left: auto; display: block; border-top-width: 0px; margin-right: auto" border="0" alt="image" src="/content/binary/WindowsLiveWriter/IclosemyBBVACompassaccountbecausetheybel_13580/image_thumb.png" width="470" height="122"></a></p> <p>In developer terms that 4-12 alphanumeric only. You cannot use any special characters or spaces. I’m not a security expert so I reached out to <a href="https://twitter.com/troyhunt">@TroyHunt</a> (founder of <a title="https://haveibeenpwned.com/" href="https://haveibeenpwned.com/">https://haveibeenpwned.com/</a> and recognized security expert) to see what his thoughts were on this. Here is <a href="https://twitter.com/troyhunt/status/537882940877721601">his response</a>.</p> <p><a href="/content/binary/WindowsLiveWriter/IclosemyBBVACompassaccountbecausetheybel_13580/image_4.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; float: none; margin-left: auto; display: block; border-top-width: 0px; margin-right: auto" border="0" alt="image" src="/content/binary/WindowsLiveWriter/IclosemyBBVACompassaccountbecausetheybel_13580/image_thumb_1.png" width="591" height="250"></a></p> <p>Later in the conversation <a href="https://twitter.com/troyhunt/status/537882940877721601">BBVACompass chimed in</a> stating</p> <p><a href="/content/binary/WindowsLiveWriter/IclosemyBBVACompassaccountbecausetheybel_13580/image_6.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; float: none; margin-left: auto; display: block; border-top-width: 0px; margin-right: auto" border="0" alt="image" src="/content/binary/WindowsLiveWriter/IclosemyBBVACompassaccountbecausetheybel_13580/image_thumb_2.png" width="583" height="100"></a> </p> <p>So I looked at the link <a title="http://www.bbvacompass.com/customer-service/online-banking/siteid.jsp" href="http://www.bbvacompass.com/customer-service/online-banking/siteid.jsp">http://www.bbvacompass.com/customer-service/online-banking/siteid.jsp</a> to see if there was some other way to authenticate which was more secure. From what I understood from that link they have a service called “Site ID” which consists of the following.</p> <ol> <li>You enter three security questions/answers <li>When logging in on a new machine you are prompted for security questions/answers and if the machine is “trusted” <li>When logging in using a trusted machine the password is never submitted over the wire</li></ol> <p>The page that was linked to didn’t include any indication that this was “dual factor authentication” as the @BBVACompass twitter account tried to pass on me. I let them know that this is not two/dual factor auth. Even with “Site ID” if you log in on a compromised machine all security questions/answers and password can be stolen and users can effectively log in without me ever being notified. That defeats the purpose of two factor auth. With two factor auth if I sign into google on a compromised machine you will get my password but when you try and sign in later you’ll have to get access to my phone’s text messages as well. That is true two factor auth, not security questions. </p> <p>Another security expert <a href="https://twitter.com/RobHale77">@RobHale77</a> also chimed in later with the comments below.</p> <p><a href="/content/binary/WindowsLiveWriter/IclosemyBBVACompassaccountbecausetheybel_13580/image_8.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; float: none; margin-left: auto; display: block; border-top-width: 0px; margin-right: auto" border="0" alt="image" src="/content/binary/WindowsLiveWriter/IclosemyBBVACompassaccountbecausetheybel_13580/image_thumb_3.png" width="588" height="98"></a></p> <h3>What’s a strong password?</h3> <p>I decided to do a bit more investigation around how BBVACompass is representing password strength on their change password page. I guessed that the password strength field was being populated with JavaScript so I opened the site in my browser and use the in-browser dev tools to look at the code. Here is the getPasswordStrength function, comments were added by me.</p><pre class="brush: js;">// This function will return an integer in the range of 0-100. // The max that I've seen here is 90 function getPasswordStrength(H){ var D=(H.length); if (D&lt;4) { D=0; } if(D&gt;5){ D=5; } var F=H.replace(/[0-9]/g,""); var G=(H.length-F.length); if(G&gt;3){G=3;} var A=H.replace(/\W/g,""); var C=(H.length-A.length); if(C&gt;3){C=3;} var B=H.replace(/[A-Z]/g,""); var I=(H.length-B.length); if(I&gt;3){I=3;} var E=((D*10)-20)+(G*10)+(C*15)+(I*10); if(E&lt;0){E=0;} if(E&gt;100){E=100;} return E; } </pre> <p>Then this is converted to weak/medium/strong with the following js function, once again comments were added by me.</p><pre class="brush: js;">$.fn.passwordStrength = function( options ){ return this.each(function(){ var that = this;that.opts = {}; that.opts = $.extend({}, $.fn.passwordStrength.defaults, options); that.div = $(that.opts.targetDiv); that.defaultClass = that.div.attr('class'); // opts.classes is declared elsewhere as = Array('weak','medium','strong') so length is 3 that.percents = (that.opts.classes.length) ? 100 / that.opts.classes.length : 100; v = $(this) .keyup(function(){ if( typeof el == "undefined" ) this.el = $(this); var s = getPasswordStrength (this.value); var p = this.percents; var t = Math.floor( s / p ); // from what I can tell 's' will max out at 90 so this if statement will always be skipped if( 100 &lt;= s ) t = this.opts.classes.length - 1; // t now determines the index for weak/medium/strong // weak: s &lt;= 30 // medium: s 40-60 (inclusive) // strong: s &gt;= 70 (maximum I've seen is 90) this.div .removeAttr('class') .addClass( this.defaultClass ) .addClass( this.opts.classes[ t ] ); }); }); </pre> <p>Since the code is minified it somewhat difficult to follow. What I found was that a strong password consisted of the following.</p> <ul> <li>3 numbers <li>1 upper case letter <li>1 lower case letter</li></ul> <p>So I decided to try “Hi123” to see if I was right. Sure enough <strong>BBVACompass told me that </strong>the selected password <strong>Hi123 is a Strong password!</strong></p> <p><a href="/content/binary/WindowsLiveWriter/IclosemyBBVACompassaccountbecausetheybel_13580/image_10.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; float: none; margin-left: auto; display: block; border-top-width: 0px; margin-right: auto" border="0" alt="image" src="/content/binary/WindowsLiveWriter/IclosemyBBVACompassaccountbecausetheybel_13580/image_thumb_4.png" width="326" height="128"></a> This is beyond insane. It contains a word and a sequence of 3 numbers (<em>likely the most common sequence at that as well</em>). BBVACompass, this is misleading at best. This is nowhere near strong, you are lying to your customers about the security of their passwords. Here are some passwords and how BBVACompass represents their strength. If you have an account you can verify this by going to the change password screen under Online Banking Profile.</p> <p><strong><u>weak</u></strong></p> <ul> <li>aaaa <li>bbbb <li>swrxwuppzx <li>hlzzeseiyg </li></ul> <p><strong><u>medium</u></strong></p> <ul> <li>1234 <li>a123 <li>HLZzESeiYG <li>sWrXwUppZX </li></ul> <p><strong><u>strong</u></strong></p> <ul> <li>Hi123 <li>123Ab <li>123Food <li>111Hi <li>111Aa</li></ul> <p>Why on earth is “hlzzeseiyg” <strong>weak</strong> and “111Aa” is <strong>strong</strong>?! Clearly this has been poorly implemented and misleading, fix it now.</p> <h3>What I would like to see as a consumer</h3> <p>My top recommendation for BBVACompass is to get a security expert/team involved to redo your online security, but if you cannot afford that then follow what’s below.</p> <p>I’m not a security expert but here is <a href="https://twitter.com/sayedihashimi/status/538433011914919936">what I recommended to BBVACompass</a> as a consumer.</p> <ol> <li>Support for very strong passwords. Those that are &gt;= 20 characters and allowing special characters <li>Support for true two factor auth like password/text or password/call <li>(<em>stretch goal</em>) Support to view an audit log of devices that have recently accessed my account</li></ol> <p>I am getting all of the above features from google currently.</p> <h3>Be more transparent about weak passwords</h3> <p>Now that I’ve seen the guts of their getPasswordStrength function I’d like to see BBVACompass implement a better function for reporting password strength. One that takes into account dictionary words, and common patterns. As stated I’m not a security expert but after a quick search I found <a title="http://www.sitepoint.com/5-bootstrap-password-strength-metercomplexity-demos/" href="http://www.sitepoint.com/5-bootstrap-password-strength-metercomplexity-demos/">http://www.sitepoint.com/5-bootstrap-password-strength-metercomplexity-demos/</a> which includes a pointer to live demo jquery.pwstrength.bootstrap (<a title="http://jsfiddle.net/jquery4u/mmXV5/" href="http://jsfiddle.net/jquery4u/mmXV5/">http://jsfiddle.net/jquery4u/mmXV5/</a>) and StrongPass.js (<a title="http://jsfiddle.net/dimitar/n8Dza/" href="http://jsfiddle.net/dimitar/n8Dza/">http://jsfiddle.net/dimitar/n8Dza/</a>). Below are the results for the same “Hi123” password from both.</p> <p><a href="/content/binary/WindowsLiveWriter/IclosemyBBVACompassaccountbecausetheybel_13580/image_12.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; float: none; margin-left: auto; display: block; border-top-width: 0px; margin-right: auto" border="0" alt="image" src="/content/binary/WindowsLiveWriter/IclosemyBBVACompassaccountbecausetheybel_13580/image_thumb_5.png" width="340" height="203"></a></p> <p><a href="/content/binary/WindowsLiveWriter/IclosemyBBVACompassaccountbecausetheybel_13580/image_14.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; float: none; margin-left: auto; display: block; border-top-width: 0px; margin-right: auto" border="0" alt="image" src="/content/binary/WindowsLiveWriter/IclosemyBBVACompassaccountbecausetheybel_13580/image_thumb_6.png" width="186" height="93"></a>&nbsp; </p> <p>As you can see if BBVACompass had used readily available Open Source tools to verify password strength we wouldn’t be having this conversation. Both reported the password as being unacceptable.</p> <h3>Accountability</h3> <p><strong>As consumers we must hold our online service providers (especially banks) accountable for online security</strong>. For the tech savy bunch, it’s your responsibility to educate your non-tech friends/family about online security and strong passwords.</p> <p><strong>As a bank, BBVACompass, needs to hold their development team accountable</strong> for providing customers with secure access to accounts online as well as <strong>honest indications for password strength</strong>. You’re being dishonest, which means I cannot trust you.</p> <p>&nbsp;</p> <h3>Previous pleas ignored by BBVACompass</h3> <p>I did a search on twitter for @BBVACompass password and discovered that this has been brought up multiple times by customers. The first of which I found occurred in November 2013! Tweets below.</p> <p align="center"><a href="/content/binary/WindowsLiveWriter/IclosemyBBVACompassaccountbecausetheybel_13580/image_16.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; float: none; margin-left: auto; display: block; border-top-width: 0px; margin-right: auto" border="0" alt="image" src="/content/binary/WindowsLiveWriter/IclosemyBBVACompassaccountbecausetheybel_13580/image_thumb_7.png" width="588" height="106"></a><a title="https://twitter.com/gumnos/status/406880230670749696" href="https://twitter.com/gumnos/status/406880230670749696">https://twitter.com/gumnos/status/406880230670749696</a></p> <p align="center"><a href="/content/binary/WindowsLiveWriter/IclosemyBBVACompassaccountbecausetheybel_13580/image_18.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; float: none; margin-left: auto; display: block; border-top-width: 0px; margin-right: auto" border="0" alt="image" src="/content/binary/WindowsLiveWriter/IclosemyBBVACompassaccountbecausetheybel_13580/image_thumb_8.png" width="582" height="99"></a></p> <p align="center"><a title="https://twitter.com/JasonSamfield/status/429448195119136768" href="https://twitter.com/JasonSamfield/status/429448195119136768">https://twitter.com/JasonSamfield/status/429448195119136768</a>&nbsp;</p> <p align="center"><a href="/content/binary/WindowsLiveWriter/IclosemyBBVACompassaccountbecausetheybel_13580/image_20.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; float: none; margin-left: auto; display: block; border-top-width: 0px; margin-right: auto" border="0" alt="image" src="/content/binary/WindowsLiveWriter/IclosemyBBVACompassaccountbecausetheybel_13580/image_thumb_9.png" width="571" height="103"></a><a title="https://twitter.com/BenLake5/status/477262736208822273" href="https://twitter.com/BenLake5/status/477262736208822273">https://twitter.com/BenLake5/status/477262736208822273</a> </p> <p align="left">BBVACompass, your customers have spoken and we are demanding better online security. <strong>Now is the time to act</strong>. I’ve already closed my account and I’ll be advising all friends/family with a BBVACompass account to do the same. With recent security breaches of Sony/Target/etc you need to start taking online security more seriously. This blog post and twitter comments may end up with a few accounts closing, but if your customers experience wide spread hacking then it will be much more severe. Fix this before it is too late, <strong>this should be your top development priority IMO</strong>.</p> <p></p> <p></p> <p></p> <h3>My Promise to BBVACompass</h3> <p>BBVACompass if you support passwords &gt;= 20 characters with special charcters within 90 days I will re-open my account with the same funds as which I closed it the next time I’m in Florida.</p> <p>&nbsp;</p> <p>Note: please post comments at <a title="http://www.reddit.com/r/technology/comments/2o4uat/i_closed_my_bbvacompass_account_because_they/" href="http://www.reddit.com/r/technology/comments/2o4uat/i_closed_my_bbvacompass_account_because_they/">http://www.reddit.com/r/technology/comments/2o4uat/i_closed_my_bbvacompass_account_because_they/</a>.</p> <p>Sayed Ibrahim Hashimi <a href="https://twitter.com/BenLake5/status/477262736208822273">@SayedIHashimi</a></p></div>https://sedodream.com/2014/12/03/i-closed-my-bbvacompass-account-because-they-believe-that-hi123-is-a-strong-password/comments#comments-starthttps://sedodream.com/feed/trackback/a71cf8b5-84bb-4294-bed9-f67865ecd866https://sedodream.com/feed/pingbackhttps://sedodream.com/post/a71cf8b5-84bb-4294-bed9-f67865ecd866https://sedodream.com/2014/08/11/slowcheetah-is-going-into-maintenance-mode/comments#comments-starthttps://sedodream.com/feed/rss/comments/a71cf8b5-84bb-4294-bed9-f67865ecd866SlowCheetah is going into maintenance modehttps://sedodream.com/post/a71cf8b5-84bb-4294-bed9-f67865ecd866https://sedodream.com/2014/08/11/slowcheetah-is-going-into-maintenance-modeMon, 11 Aug 2014 17:44:36 GMT<div><p><strong>For the latest info here and for discussion please visit </strong><a title="https://github.com/sayedihashimi/slow-cheetah/issues/158" href="https://github.com/sayedihashimi/slow-cheetah/issues/158"><strong>https://github.com/sayedihashimi/slow-cheetah/issues/158</strong></a><strong>.</strong></p> <p>&nbsp;</p> <p>I first developed SlowCheetah around VS2010 SP2 with the idea that I could at some point transition this to the appropriate team(s) at Microsoft. Unfortunately I haven't been able to do that, and the existence of this extension has actually worked against that goal.</p> <p>I'm really happy that SlowCheetah has gotten the attention and success that it has, but now it's time for me to move on. <h5>No support for SlowCheetah in VS "14"</h5> <p>I am not planning to update SlowCheetah for Visual Studio "14". If you would like to see support for transforms in VS "14" I suggest you vote, <strong><em>and comment</em></strong>, on the uesrvoice item at <a href="http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/2043217-support-web-config-style-transforms-on-any-file-in">http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/2043217-support-web-config-style-transforms-on-any-file-in</a>. <h5>No new features</h5> <p>I will not be adding any features to SlowCheetah myself. If anyone want's to add any features I will try and help guide anyone who is interested. <h5>No fixes for regressions</h5> <p>If there are any scenarios that work in VS2013 RTM that do not work in future version of Visual Studio then I will not be fixing them. <p>I hope you all understand my situation here. I have spent countless hours working on SlowCheetah and there is very little ROI for me so, I need to move on to focus on other OSS projects that I'm involved in. <p>Thanks for all the love. I still love SlowCheetah too and I'm sad to see there won't be support for transform in VS "14" <p>&nbsp; <p>Thanks, <p>Sayed Ibrahim Hashimi | <a href="http://msbuildbook.com">http://msbuildbook.com</a> | <a href="https://twitter.com/sayedihashimi">@SayedIHashimi</a></p></div>https://sedodream.com/2014/08/11/slowcheetah-is-going-into-maintenance-mode/comments#comments-startMSBuildSlowCheetahVisual Studiohttps://sedodream.com/feed/trackback/25959653-16c0-4047-96d6-73984346624bhttps://sedodream.com/feed/pingbackhttps://sedodream.com/post/25959653-16c0-4047-96d6-73984346624bhttps://sedodream.com/2014/07/22/stop-checkingin-binaries-instead-create-selfbootstrapping-scripts/comments#comments-starthttps://sedodream.com/feed/rss/comments/25959653-16c0-4047-96d6-73984346624bStop checking-in binaries, instead create self-bootstrapping scriptshttps://sedodream.com/post/25959653-16c0-4047-96d6-73984346624bhttps://sedodream.com/2014/07/22/stop-checkingin-binaries-instead-create-selfbootstrapping-scriptsTue, 22 Jul 2014 06:36:11 GMT<div><p>A few weeks ago <a href="http://madskristensen.net/">Mads Kristensen</a> and I created a few site extensions for Azure Web Sites which the <a href="http://www.siteextensions.net/packages/AzureImageOptimizer/">Azure Image Optimizer</a> and <a href="http://www.siteextensions.net/packages/AzureMinifier/">Azure Minifier</a>. These extensions can be used to automatically optimize all images on a site, and minify all .js/.css files respectively. These are shipped as nuget packages in <a href="http://nuget.org/">nuget.org</a> as well as site extensions in <a href="http://siteextensions.net">siteextensions.net</a>.</p> <p>After creating those utilities we also update the image optimizer to support being called in on the command line via a .exe. We have not yet had a chance to update the minifier to be callable directly but we have an <a href="https://github.com/ligershark/AzureJobs/issues/26">open issue on it</a>. If you can help that would be great.</p> <p>The exe for the image optimizer that can be used from the command line can be found in <a href="https://www.nuget.org/packages/AzureImageOptimizer/">the nuget package</a> as well. You can also download it from <a href="https://dl.dropboxusercontent.com/u/40134810/azurejobs/AzureImageOptimizer.0.0.11-beta-cmdline.zip">here</a>, but to get the latest version you nuget.org is the way to go.</p> <p>After releasing that exe I wanted an easy way to use it on a variety of machines, and to make it simple for others to try it out. What I ended up with is what I’m calling a “self-bootstrapping script” which you can find at <a href="https://github.com/ligershark/AzureJobs/blob/master/ImageCompressor.Job/optimize-images.ps1">optimize-images.ps1</a>. Below you’ll see the entire contents of the script.</p><pre class="brush: powershell;">[cmdletbinding()] param( $folderToOptimize = ($pwd), $toolsDir = ("$env:LOCALAPPDATA\LigerShark\tools\"), $nugetDownloadUrl = 'http://nuget.org/nuget.exe' ) &lt;# .SYNOPSIS If nuget is in the tools folder then it will be downloaded there. #&gt; function Get-Nuget(){ [cmdletbinding()] param( $toolsDir = ("$env:LOCALAPPDATA\LigerShark\tools\"), $nugetDownloadUrl = 'http://nuget.org/nuget.exe' ) process{ $nugetDestPath = Join-Path -Path $toolsDir -ChildPath nuget.exe if(!(Test-Path $nugetDestPath)){ 'Downloading nuget.exe' | Write-Verbose (New-Object System.Net.WebClient).DownloadFile($nugetDownloadUrl, $nugetDestPath) # double check that is was written to disk if(!(Test-Path $nugetDestPath)){ throw 'unable to download nuget' } } # return the path of the file $nugetDestPath } } &lt;# .SYNOPSIS If the image optimizer in the .ools folder then it will be downloaded there. #&gt; function GetImageOptimizer(){ [cmdletbinding()] param( $toolsDir = ("$env:LOCALAPPDATA\LigerShark\tools\"), $nugetDownloadUrl = 'http://nuget.org/nuget.exe' ) process{ if(!(Test-Path $toolsDir)){ New-Item $toolsDir -ItemType Directory | Out-Null } $imgOptimizer = (Get-ChildItem -Path $toolsDir -Include 'ImageCompressor.Job.exe' -Recurse) if(!$imgOptimizer){ 'Downloading image optimizer to the .tools folder' | Write-Verbose # nuget install AzureImageOptimizer -Prerelease -OutputDirectory C:\temp\nuget\out\ $cmdArgs = @('install','AzureImageOptimizer','-Prerelease','-OutputDirectory',(Resolve-Path $toolsDir).ToString()) 'Calling nuget to install image optimzer with the following args. [{0}]' -f ($cmdArgs -join ' ') | Write-Verbose &amp;(Get-Nuget -toolsDir $toolsDir -nugetDownloadUrl $nugetDownloadUrl) $cmdArgs | Out-Null } $imgOptimizer = Get-ChildItem -Path $toolsDir -Include 'ImageCompressor.Job.exe' -Recurse | select -first 1 if(!$imgOptimizer){ throw 'Image optimizer not found' } $imgOptimizer } } function OptimizeImages(){ [cmdletbinding()] param( [Parameter(Mandatory=$true,Position=0)] $folder, $toolsDir = ("$env:LOCALAPPDATA\LigerShark\tools\"), $nugetDownloadUrl = 'http://nuget.org/nuget.exe' ) process{ [string]$imgOptExe = (GetImageOptimizer -toolsDir $toolsDir -nugetDownloadUrl $nugetDownloadUrl) [string]$folderToOptimize = (Resolve-path $folder) 'Starting image optimizer on folder [{0}]' -f $folder | Write-Host # .\.tools\AzureImageOptimizer.0.0.10-beta\tools\ImageCompressor.Job.exe --folder M:\temp\images\opt\to-optimize $cmdArgs = @('--folder', $folderToOptimize) 'Calling img optimizer with the following args [{0} {1}]' -f $imgOptExe, ($cmdArgs -join ' ') | Write-Host &amp;$imgOptExe $cmdArgs 'Images optimized' | Write-Host } } OptimizeImages -folder $folderToOptimize -toolsDir $toolsDir -nugetDownloadUrl $nugetDownloadUrl </pre> <p>The script is setup to where you call functions like <font size="3" face="Consolas">Get-NuGet</font> and <font size="3" face="con">GetImageOptimzer</font> to get the path to the .exe to call. If the .exe is not in the expected location, under %localappdata% by default, it will be downloaded and then the path will be returned. In the case of this script I use nuget.org as my primary distribution mechanism for this so the script will first download nuget.exe and then use that to get the actual binaries. WIth this approach, you can avoid checking in binaries and have scripts which are still pretty concise.</p> <p>After creating optimize-images.ps1 I thought it would be really useful to have a similar script to execute XDT transforms on xml files. So I created <a href="https://gist.github.com/sayedihashimi/f1fdc4bfba74d398ec5b">transform-xml.ps1</a>. That script first downloads nuget.exe and then uses that to download the nuget packages which are required to invoke XDT transforms. </p> <p>A self-bootstrapping script doesn’t need to be a PowerShell script, you can apply the same techniques to any scripting language. I’ve recently created an MSBuild script, inspired by Get-Nuget above, which can be used in a similar way. You can find that script in a <a href="https://gist.github.com/sayedihashimi/64736331b273162a1e76">gist here</a>. It’s below as well. </p><pre class="brush: xml;">&lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="GetNuget"&gt; &lt;!-- This is an MSBuild snippet that can be used to download nuget to the path in the property NuGetExePath property. Usage: 1. Import this file or copy and paste this into your build script 2. Call the GetNuGet target before you use nuget.exe from $(NuGetExePath) --&gt; &lt;PropertyGroup&gt; &lt;NuGetExePath Condition=" '$(NuGetExePath)'=='' "&gt;$(localappdata)\LigerShark\AzureJobs\tools\nuget.exe&lt;/NuGetExePath&gt; &lt;NuGetDownloadUrl Condition=" '$(NuGetDownloadUrl)'=='' "&gt;http://nuget.org/nuget.exe&lt;/NuGetDownloadUrl&gt; &lt;/PropertyGroup&gt; &lt;Target Name="GetNuget" Condition="!Exists('$(NuGetExePath)')"&gt; &lt;Message Text="Downloading nuget from [$(NuGetDownloadUrl)] to [$(NuGetExePath)]" Importance="high"/&gt; &lt;ItemGroup&gt; &lt;_nugetexeitem Include="$(NuGetExePath)" /&gt; &lt;/ItemGroup&gt; &lt;MakeDir Directories="@(_nugetexeitem-&gt;'%(RootDir)%(Directory)')"/&gt; &lt;DownloadFile Address="$(NuGetDownloadUrl)" FileName="$(NuGetExePath)" /&gt; &lt;/Target&gt; &lt;PropertyGroup Condition=" '$(ls-msbuildtasks-path)'=='' "&gt; &lt;ls-msbuildtasks-path&gt;$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll&lt;/ls-msbuildtasks-path&gt; &lt;ls-msbuildtasks-path Condition=" !Exists('$(ls-msbuildtasks-path)')"&gt;$(MSBuildFrameworkToolsPath)\Microsoft.Build.Tasks.v4.0.dll&lt;/ls-msbuildtasks-path&gt; &lt;ls-msbuildtasks-path Condition=" !Exists('$(ls-msbuildtasks-path)')"&gt;$(windir)\Microsoft.NET\Framework\v4.0.30319\Microsoft.Build.Tasks.v4.0.dll&lt;/ls-msbuildtasks-path&gt; &lt;/PropertyGroup&gt; &lt;UsingTask TaskName="DownloadFile" TaskFactory="CodeTaskFactory" AssemblyFile="$(ls-msbuildtasks-path)"&gt; &lt;!-- http://stackoverflow.com/a/12739168/105999 --&gt; &lt;ParameterGroup&gt; &lt;Address ParameterType="System.String" Required="true"/&gt; &lt;FileName ParameterType="System.String" Required="true" /&gt; &lt;/ParameterGroup&gt; &lt;Task&gt; &lt;Reference Include="System" /&gt; &lt;Code Type="Fragment" Language="cs"&gt; &lt;![CDATA[ new System.Net.WebClient().DownloadFile(Address, FileName); ]]&gt; &lt;/Code&gt; &lt;/Task&gt; &lt;/UsingTask&gt; &lt;/Project&gt; </pre> <p>This script has a single target, <font size="3" face="Consolas">GetNuGet</font>, which you can call to download nuget.exe to the expected location. After that you can use the path to nuget.exe from the NuGetExePath property. I’ve already removed nuget.ext from <a href="https://github.com/ligershark/side-waffle">SideWaffle</a> and <a href="https://github.com/ligershark/AzureJobs">AzureJobs</a> repository using this technique. It’s a great way to avoid checking in nuget.exe.</p> <p>&nbsp;</p> <p>Thanks,<br>Sayed Ibrahim Hashimi | <a href="http://msbuildbook.com">http://msbuildbook.com</a> | <a href="https://twitter.com/sayedihashimi">@SayedIHashimi</a></p></div>https://sedodream.com/2014/07/22/stop-checkingin-binaries-instead-create-selfbootstrapping-scripts/comments#comments-startMSBuildpowershellscriptinghttps://sedodream.com/feed/trackback/545b31fa-3ef8-4c51-8347-7df101960b14https://sedodream.com/feed/pingbackhttps://sedodream.com/post/545b31fa-3ef8-4c51-8347-7df101960b14https://sedodream.com/2014/07/19/introducing-psbuild-an-improved-interface-for-msbuildexe-in-powershell/comments#comments-starthttps://sedodream.com/feed/rss/comments/545b31fa-3ef8-4c51-8347-7df101960b14Introducing PSBuild – an improved interface for msbuild.exe in PowerShellhttps://sedodream.com/post/545b31fa-3ef8-4c51-8347-7df101960b14https://sedodream.com/2014/07/19/introducing-psbuild-an-improved-interface-for-msbuildexe-in-powershellSat, 19 Jul 2014 05:20:43 GMT<div><p>For the past few months I’ve been working on a project I’m calling <a href="https://github.com/ligershark/psbuild">PSBuild</a>. It’s an open source project on GitHub which makes the experience of calling MSBuild from PowerShell better. Getting started with PSBuild is really easy. You can install it in one line.</p><pre class="brush: bash;">(new-object Net.WebClient).DownloadString("https://raw.github.com/ligershark/psbuild/master/src/GetPSBuild.ps1") | iex </pre> <p>You can find this info on the <a href="https://github.com/ligershark/psbuild">project home page</a> as well. </p> <p>&nbsp;</p> <p>When you install PSBuild one of the functions that you get is <font face="Consolas">Invoke-MSBuild</font>. When you call <font face="Consolas">Invoke-MSBuild</font> it will end up calling msbuild.exe. Some advantages of using Invoke-MSBuild are.</p> <ul> <ul></ul> <li> <p>It uses the latest version of msbuild.exe installed by default</p></li> <li> <p>Mult-core builds by default</p></li> <li> <p>Writes a detailed and diagnostic log to %localappdata% by default. It’s easy to get to those logs as well</p></li> <li> <p>Good defaults for logging, including console logger</p></li> <li> <p>You can pass more than one file to build</p></li> <li> <p>Support for “Default Properties”</p></li></ul> <h3>Calling Invoke-MSBuild</h3> <p>A most basic usage of Invoke-MSBuild.</p><pre class="brush: bash;">Invoke-MSBuild .\App.csproj </pre> <p>This will build the project using the default targets. The call to msbuild.exe on my computer is below.</p><pre class="brush: bash;">C:\Program Files (x86)\MSBuild\12.0\bin\amd64\msbuild.exe .\App.csproj /m /clp:v=m /flp1:v=d;logfile=C:\Users\Sayed\AppData\Local\PSBuild\logs\App.csproj-log\msbuild.detailed.log /flp2:v=diag;logfile=C:\Users\Sayed\AppData\Local\PSBuild\logs\App.csproj-log\msbuild.diagnostic.log</pre> <p>From the call to msbuild.exe you can see that the /m is passed as well as a couple file loggers in %localappdata%. We will get to the logs later. More on Invoke-MSBuild,</p> <p>To get a sense for how you can use Invoke-MSBuild take a look at the examples below.</p><pre class="brush: bash;"> # VisualStudioVersion and Configuration MSBuild properties have easy to use parameters Invoke-MSBuild .\App.csproj -visualStudioVersion 12.0 -configuration Release # How to pass properties Invoke-MSBuild .\App.csproj -visualStudioVersion 12.0 -properties @{'DeployOnBuild'='true';'PublishProfile'='toazure';'Password'='mypwd-really'} # How to build a single target Invoke-MSBuild .\App.csproj -visualStudioVersion 12.0 -targets Clean # How to bulid multiple targets Invoke-MSBuild .\App.csproj -visualStudioVersion 12.0 -targets @('Clean','Build') </pre> <p>&nbsp;</p> <h3>Getting log files</h3> <p></p> <p>When you call Invoke-MSBuild on a project or solution the output will look something like the following.</p> <p><a href="/content/binary/WindowsLiveWriter/IntroducingPSBuild_12DAC/image_4.png"><img title="image" style="border-top: 0px; border-right: 0px; border-bottom: 0px; border-left: 0px; display: inline" border="0" alt="image" src="/content/binary/WindowsLiveWriter/IntroducingPSBuild_12DAC/image_thumb_1.png" width="1124" height="102"></a> </p> <p>Notice that line at the end. You can access your last log using the command.</p><pre class="brush: bash;">Open-PSBuildLog </pre> <p>This will open the detailed log of the previous build in the program that’s associated with the .log extension. You can also use the <strong><font size="3" face="Consolas">Get-PSBuildLastLogs</font></strong> function to view the path for both log files written. If you want to view the folder where the log files are written to you can execute <strong><font size="3" face="conso">start (Get-PSBuildLogDirectory)</font></strong>.</p> <h3>Helper functions</h3> <p>There are a couple of things that I’m constantly having to look up when I’m authoring MSBuild files; Reserved property names and escape characters. PSBuild has a helper function for each of these <strong><font size="3" face="Consolas">Get-MSBuildEscapeCharacters</font></strong> and <strong><font size="3" face="cons">Get-MSBuildReservedProperties</font></strong>. In the screenshot below you’ll see the result of executing each of these.</p> <p><a href="/content/binary/WindowsLiveWriter/IntroducingPSBuild_12DAC/image_6.png"><img title="image" style="border-top: 0px; border-right: 0px; border-bottom: 0px; border-left: 0px; display: inline" border="0" alt="image" src="/content/binary/WindowsLiveWriter/IntroducingPSBuild_12DAC/image_thumb_2.png" width="1124" height="619"></a> </p> <p>&nbsp;</p> <h3>Default Properties</h3> <p>The Invoke-MSBuild cmdlet has a property <strong><font size="3" face="Consolas">–defaultProperties</font></strong>. You can pass in a hashtable just like the <strong><font size="3" face="Consolas">–properties</font></strong> parameter. These properties are applied as environment variables before the call to msbuild.exe and then reverted afterwards. The effect here is that you can have a property value which will be used if no other value for that property is specified in MSBuild.</p> <p>&nbsp;</p> <p>There is so much more to PSBuild. This is just the tip of the iceberg. Keep an eye on the project page for more info. I’d love your help on this project. Please consider contributing to the project <a title="https://github.com/ligershark/psbuild" href="https://github.com/ligershark/psbuild">https://github.com/ligershark/psbuild</a>.</p> <p>&nbsp;</p> <p>Thanks,<br>Sayed Ibrahim Hashimi | <a href="http://msbuildbook.com/">http://msbuildbook.com/</a> | @SayedIHashimi</p></div>https://sedodream.com/2014/07/19/introducing-psbuild-an-improved-interface-for-msbuildexe-in-powershell/comments#comments-startMSBuildpsbuildhttps://sedodream.com/feed/trackback/c884bc0b-973e-40a3-b311-ef7685fe8e64https://sedodream.com/feed/pingbackhttps://sedodream.com/post/c884bc0b-973e-40a3-b311-ef7685fe8e64https://sedodream.com/2014/05/08/how-to-download-a-site-using-msdeployexe/comments#comments-starthttps://sedodream.com/feed/rss/comments/c884bc0b-973e-40a3-b311-ef7685fe8e64How to download a site using msdeploy.exehttps://sedodream.com/post/c884bc0b-973e-40a3-b311-ef7685fe8e64https://sedodream.com/2014/05/08/how-to-download-a-site-using-msdeployexeThu, 08 May 2014 23:02:02 GMT<div><p>Recently I encountered a customer asking if it’s possible to download a site using msdeploy.exe. This is pretty easy using msdeploy.exe. I’ll demonstrate this with Microsoft Azure Web Sites but you can use this with any hosting provider that supports Web Deploy (aka MSDeploy).</p> <p>To perform a sync with msdeploy.exe the structure of the command that we need to execute is as follows.</p> <blockquote> <p>msdeploy.exe –verb:sync –source:&lt;fill-in-details&gt; –dest:&lt;fill-in-details&gt;</p></blockquote> <p>For the source property we will use the remote Azure Web Site, and for the dest property we will write to a folder on the local file system. You can get the Web Deploy publishing settings in the Azure Web Site by clicking on the <strong>Download the publish profile</strong> link in the Configure page.</p> <p><a href="/content/binary/WindowsLiveWriter/Howtodownloadasiteusingmsdeploy.exe_D54B/image_2.png"><img title="image" style="display: inline" border="0" alt="image" src="/content/binary/WindowsLiveWriter/Howtodownloadasiteusingmsdeploy.exe_D54B/image_thumb.png" width="228" height="244"></a> </p> <p>This will download an XML file that has all the publish settings you’ll need. For example below is a publish settings file for my demo site.</p><pre class="brush: xml;">&lt;publishData&gt; &lt;publishProfile profileName="sayeddemo2 - Web Deploy" publishMethod="MSDeploy" publishUrl="waws-prod-bay-001.publish.azurewebsites.windows.net:443" msdeploySite="sayeddemo2" userName="$sayeddemo2" userPWD="*** removed ***" destinationAppUrl="http://sayeddemo2.azurewebsites.net" SQLServerDBConnectionString="" mySQLDBConnectionString="" hostingProviderForumLink="" controlPanelLink="http://windows.azure.com"&gt; &lt;databases/&gt; &lt;/publishProfile&gt; &lt;publishProfile profileName="sayeddemo2 - FTP" publishMethod="FTP" publishUrl="ftp://waws-prod-bay-001.ftp.azurewebsites.windows.net/site/wwwroot" ftpPassiveMode="True" userName="sayeddemo2\$sayeddemo2" userPWD="*** removed ***" destinationAppUrl="http://sayeddemo2.azurewebsites.net" SQLServerDBConnectionString="" mySQLDBConnectionString="" hostingProviderForumLink="" controlPanelLink="http://windows.azure.com"&gt; &lt;databases/&gt; &lt;/publishProfile&gt; &lt;/publishData&gt;</pre> <p>The publish settings file provided by Azure Web Sites has two profiles; an MSDeploy profile and an FTP profile. We can ignore the FTP profile and just use the MSDeploy one. The relevant settings from the profile that we will use are the following values.</p> <ul> <li>publishUrl <li>msdeploySite <li>userName <li>usePWD</li></ul> <p>We will use the contentPath MSDeploy provider to download the files. On the source parameter we will need to include the relevant details of the remote machine. The full command to execute is below. I’ll break it down a bit after the snippet.</p><pre class="brush: xml;">"C:\Program Files (x86)\IIS\Microsoft Web Deploy V3\msdeploy.exe" -verb:sync -source:contentPath=sayeddemo2, ComputerName="https://waws-prod-bay-001.publish.azurewebsites.windows.net/msdeploy.axd?site=sayeddemo2", UserName=$sayeddemo2,Password=***removed***,AuthType='Basic' -dest:contentPath=c:\temp\pubfromazure -disablerule:BackupRule </pre> <p>The important parts of the command above are how the remote settings are passed to the source provider. On the dest side I’ve provided the location where the files should be downloaded to.</p> <p>&nbsp;</p> <p>Sayed Ibrahim Hashimi | <a href="http://msbuildbook.com/">http://msbuildbook.com/</a> | <a href="https://twitter.com/sayedihashimi">@SayedIHashimi</a></p></div>https://sedodream.com/2014/05/08/how-to-download-a-site-using-msdeployexe/comments#comments-starthttps://sedodream.com/feed/trackback/77e46179-7ed7-4741-af4d-47148e9a74a1https://sedodream.com/feed/pingbackhttps://sedodream.com/post/77e46179-7ed7-4741-af4d-47148e9a74a1https://sedodream.com/2013/10/11/sidewaffle-how-to-create-your-own-vs-template-pack/comments#comments-starthttps://sedodream.com/feed/rss/comments/77e46179-7ed7-4741-af4d-47148e9a74a1SideWaffle: How to create your own VS template packhttps://sedodream.com/post/77e46179-7ed7-4741-af4d-47148e9a74a1https://sedodream.com/2013/10/11/sidewaffle-how-to-create-your-own-vs-template-packFri, 11 Oct 2013 16:11:26 GMT<div><p>If you haven’t heard I’m working on a project with <a href="http://madskristensen.net/">Mads Kristensen</a> called <a href="http://sidewaffle.com/">SideWaffle</a>. SideWaffle is a Visual Studio Extension which contains many different Visual Studio Item and Project Templates. This is a community effort and all open source at <a href="https://github.com/ligershark/template-builder">https://github.com/ligershark/template-builder</a>. You can create your own Item Templates and Project Templates and send a Pull Request for them to be included in the main repo. Check out the video below for more info on SideWaffle.</p> <p><strong><u>SideWaffle intro video</u></strong></p><iframe height="315" src="//www.youtube.com/embed/bEt0MFksmpU" frameborder="0" width="420" allowfullscreen></iframe> <p>Item Templates are used by VS developers to create files using the Add New Item dialog. SideWaffle already contains a number of Item Templates such as; Angular Controller, robots.txt, SignalR Hub and Client, etc. For more info on how to create Item Templates with SideWaffle watch the 4 minute video below.</p><iframe height="315" src="//www.youtube.com/embed/naY3jbBNNgY" frameborder="0" width="420" allowfullscreen></iframe> <p>&nbsp;</p> <p>Project Templates are the items that show up in the Add New Project dialog. They provide a starting point for developers creating new projects. SideWaffle already has a few project templates as well, such as a <a href="http://www.youtube.com/watch?v=gX5RrCHNvgs">Google Chrome Extension</a>. You can learn more about how to create Project Templates in this video.</p><iframe height="315" src="//www.youtube.com/embed/NChUqnArTrI" frameborder="0" width="420" allowfullscreen></iframe> <p>&nbsp;</p> <p>Now that we’ve gotten the intro out of the way, let’s explore how you can create your own SideWaffle.</p> <h3>How to create your own SideWaffle</h3> <p>The idea behind SideWaffle is that we will have a shared VS extension for popular VS Item and Project Templates. Instead of contributing to the main SideWaffle project you may be interested in creating your own distribution that does not have the standard templates. For example, I’ve heard from both the <a href="http://orchard.codeplex.com">Orchard</a> and <a href="http://umbraco.com/">Umbraco</a> that they are interested in creating template packs for their communities. It wouldn’t make much sense to include those templates in the main SideWaffle project. Instead it would be best to create a separate distribution for each; OrchardWaffle and UmbracoWaffle.</p> <p>So how can you do this? It’s pretty easy actually. SideWaffle is built on top of a NuGet package, TemplateBuilder, which is also open source at <a href="https://github.com/ligershark/template-builder">https://github.com/ligershark/template-builder</a>. All the core functionality of SideWaffle is contained in that NuGet package. To create your own SideWaffle follow these steps:</p> <ul> <li>If you don’t have it already download and install the Visual Studio SDK, here is <a href="http://www.microsoft.com/en-us/download/details.aspx?id=30668">2012 version</a></li> <li>Create a new Visual Studio Package project</li> <li>From the package manager console execute <strong>Install-Package TemplateBuilder –pre</strong></li></ul> <p>After you add the TemplateBuilder NuGet package a few things happen:</p> <ol> <li>The build process of the project is modified to support building Item and Project templates</li> <li>Your .vsixmanifest file is updated with two new Asset tags</li> <li>An ItemTemplates folder is created with a sample Item Template</li></ol> <p>From here on you can build the project and after installing the generated .vsix you can have users easily create instances of your item or project templates.</p> <p>You can add additional Item Templates, as well as create Project Templates in your project. That’s pretty much all there is to getting started with your own Waffle pack. </p> <p>Let me know if you have any issues or comments.</p> <p>Happy Waffleing!</p> <p>&nbsp;</p> <p>Sayed Ibrahim Hashimi | <a href="http://msbuildbook.com">http://msbuildbook.com</a> | <a href="https://twitter.com/sayedihashimi">@SayedIHashimi</a></p></div>https://sedodream.com/2013/10/11/sidewaffle-how-to-create-your-own-vs-template-pack/comments#comments-startextensibilitySideWaffleVisual StudioVisual Studio 2012VSIXhttps://sedodream.com/feed/trackback/14e3bfc5-b31f-4994-917d-411e3c7d8240https://sedodream.com/feed/pingbackhttps://sedodream.com/post/14e3bfc5-b31f-4994-917d-411e3c7d8240https://sedodream.com/2013/09/21/how-to-extend-the-web-publish-process-without-modifying-project-contents/comments#comments-starthttps://sedodream.com/feed/rss/comments/14e3bfc5-b31f-4994-917d-411e3c7d8240How to extend the web publish process without modifying project contentshttps://sedodream.com/post/14e3bfc5-b31f-4994-917d-411e3c7d8240https://sedodream.com/2013/09/21/how-to-extend-the-web-publish-process-without-modifying-project-contentsSat, 21 Sep 2013 18:57:03 GMT<div><p>When automating web publishing for Visual Studio projects in many cases your first step will be to create a publish profile for the project in VS. There are many cases in which you cannot, or would not like to do this. In this post I’ll show you how you can take an existing project and use an MSBuild file to drive the publish process. In that I’ll also show how you can extend the publish process without modifying either the project or any of its contents.</p> <p>Before we get too far into this, if you are not familiar with how to publish your VS web projects from the command line you can read our docs at <a href="http://www.asp.net/mvc/tutorials/deployment/visual-studio-web-deployment/command-line-deployment">ttp://www.asp.net/mvc/tutorials/deployment/visual-studio-web-deployment/command-line-deployment</a>.</p> <p>When you publish a project from the command line using a publish profile you typically use the syntax below.</p><pre class="brush: xml;">msbuild .\MyProject.csproj /p:VisualStudioVersion=11.0 /p:DeployOnBuild=true /p:PublishProfile=&lt;profile-name-or-path&gt; </pre> <p>In this snippet we are passing in a handful of properties. VisualStudioVersion dictates which version of MSBuild targets are used during the build. See <a href="http://sedodream.com/2012/08/19/VisualStudioProjectCompatabilityAndVisualStudioVersion.aspx">http://sedodream.com/2012/08/19/VisualStudioProjectCompatabilityAndVisualStudioVersion.aspx</a> for more details on that. DeployOnBuild=true injects the publish process at the end of build. PublishProfile can either be the name of a publish profile which the project contains <strong>or it can be the full path to a publish profile</strong>. We will use PublishProfile with that second option, the full path.</p> <p>So we need to pass in the full path to a publish profile, which typically is a .pubxml file. A publish profile is just an MSBuild file. When you pass in PublishProfile and DeployOnBuild=true, then the publish profile is Imported into the build/publish process. It will supply the publish properties needed to perform the publish.</p> <p>Let’s see how that works. I have a sample project, MySite, which does not have any publish profiles created for it. I have created a publish profile, ToFileSys.pubxml, in another folder that will be used though. The contents of that file are below.</p> <p><strong><u>ToFileSys.pubxml</u></strong></p><pre class="brush: xml;">&lt;Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt; &lt;PropertyGroup&gt; &lt;WebPublishMethod&gt;FileSystem&lt;/WebPublishMethod&gt; &lt;ExcludeApp_Data&gt;False&lt;/ExcludeApp_Data&gt; &lt;publishUrl&gt;C:\temp\Publish\01&lt;/publishUrl&gt; &lt;DeleteExistingFiles&gt;False&lt;/DeleteExistingFiles&gt; &lt;/PropertyGroup&gt; &lt;/Project&gt; </pre> <p>This publish profile will publish to a local folder. I just created this file in VS with a different project and then just copied it to the folder that I needed, and removed properties which are only used for the inside of VS experience. We can publish the MySite project using this profile with the command below.</p><pre class="brush: xml;">msbuild MySite.csproj /p:VisualStudioVersion=11.0 /p:DeployOnBuild=true /p:PublishProfile=C:\data\my-code\publish-samples\publish-injection\build\ToFileSys.pubxml </pre> <p>When you execute this the file specified in PublishProfile will be included into the build process.</p> <h3>Taking it up a level</h3> <p><a href="/content/binary/WindowsLiveWriter/Howtoextendthewebpublishprocesswithoutmo_9E9F/steps_2.jpg"><img title="steps" style="border-top: 0px; border-right: 0px; border-bottom: 0px; border-left: 0px; display: inline" border="0" alt="steps" src="/content/binary/WindowsLiveWriter/Howtoextendthewebpublishprocesswithoutmo_9E9F/steps_thumb.jpg" width="644" height="445"></a> </p> <p>Now let’s see how we can take this to the next level by having a single script that will be used to publish more than one project using this technique.</p> <p>In the sample files (<em>which you can find links for at the end of the post</em>). I have a solution with two web projects, MySite and MyOtherSite. Neither of these projects have any publish profiles created. I have created a script which will build/publish these projects which you can find at <em>build\publish.proj</em> in the samples. The contents of the file are shown below.</p> <p><strong><u>publish.proj</u></strong></p><pre class="brush: xml;">&lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="BuildProjects"&gt; &lt;!-- This file is used in two ways. 1. Drive the build and publish process 2. It is used by the publish process during the build of MySite to configure/extend publish Note: 1. Is kicked off by the use on the cmd line/build server. 2. Is invoked by this script itself. This file is injected into the publish process via the PublishProfile property. --&gt; &lt;PropertyGroup&gt; &lt;VisualStudioVersion Condition=" '$(VisualStudioVersion)'=='' "&gt;11.0&lt;/VisualStudioVersion&gt; &lt;Configuration Condition=" '$(Configuration)'=='' "&gt;Release&lt;/Configuration&gt; &lt;!-- Location for build output of the project --&gt; &lt;OutputRoot Condition=" '$(OutputRoot)'=='' "&gt;$(MSBuildThisFileDirectory)..\BuildOutput\&lt;/OutputRoot&gt; &lt;!-- Root for the publish output --&gt; &lt;PublishFolder Condition=" '$(PublishFolder)'==''"&gt;C:\temp\Publish\Output\&lt;/PublishFolder&gt; &lt;/PropertyGroup&gt; &lt;ItemGroup&gt; &lt;ProjectsToBuild Include="$(MSBuildThisFileDirectory)..\MySite\MySite.csproj"&gt; &lt;AdditionalProperties&gt; VisualStudioVersion=$(VisualStudioVersion); Configuration=$(Configuration); OutputPath=$(OutputRoot); WebPublishMethod=FileSystem; publishUrl=$(PublishFolder)MySite\; DeployOnBuild=true; DeployTarget=WebPublish; PublishProfile=$(MSBuildThisFileFullPath) &lt;/AdditionalProperties&gt; &lt;/ProjectsToBuild&gt; &lt;ProjectsToBuild Include="$(MSBuildThisFileDirectory)..\MyOtherSite\MyOtherSite.csproj"&gt; &lt;AdditionalProperties&gt; VisualStudioVersion=$(VisualStudioVersion); Configuration=$(Configuration); OutputPath=$(OutputRoot); WebPublishMethod=FileSystem; publishUrl=$(PublishFolder)MyOtherSite\; DeployOnBuild=true; DeployTarget=WebPublish; PublishProfile=$(MSBuildThisFileFullPath) &lt;/AdditionalProperties&gt; &lt;/ProjectsToBuild&gt; &lt;/ItemGroup&gt; &lt;Target Name="BuildProjects"&gt; &lt;MSBuild Projects="@(ProjectsToBuild)" /&gt; &lt;/Target&gt; &lt;!-- *************************************************************************************** The targets below will be called during the publish process. These targets are injected into the publish process for each web project. These targets will not have access to any new values for properties/items from the targets above this. *************************************************************************************** --&gt; &lt;Target Name="AfterWebPublish" AfterTargets="WebPublish"&gt; &lt;Message Text="Inside AfterWebPublish" Importance="high"/&gt; &lt;/Target&gt; &lt;/Project&gt; </pre> <p>This file is pretty simple, it declares some properties which will be used for the build/publish process. Then it declares the projects to be built with an item list named <em>ProjectsToBuild</em>. When declaring <em>ProjectsToBuild</em> I use the AdditionalProperties metadata to specify MSBuild properties to be used during the build process for each project. Let’s take a closer look at those properties.</p><pre class="brush: xml;">&lt;AdditionalProperties&gt; VisualStudioVersion=$(VisualStudioVersion); Configuration=$(Configuration); OutputPath=$(OutputRoot); WebPublishMethod=FileSystem; publishUrl=$(PublishFolder)MySite\; DeployOnBuild=true; DeployTarget=WebPublish; PublishProfile=$(MSBuildThisFileFullPath) &lt;/AdditionalProperties&gt; </pre> <p>I’ll explain all the properties now. VisualStudioVersion, Configuration and OutputPath are all used for the build process. The other properties are related to publishing. If you want to publish from the file system those properties (<em>WebPublishMethod, publishUrl, DeployOnBuild, and DeployTarget</em>) must be set. The most important property there is PublishProfile.</p> <p>PublishProfile is set to $(MSBuildThisFileFullPath) which is the full path to publish.proj. This will instruct the build process of that project to import publish.proj when its build/publish process is started. It’s important to note that a “new instance” of the file will be imported. What that means is that the imported version of publish.proj won’t have access to any dynamic properties/items created in publish.proj.</p> <p>The reason why PublishProfile is specified there is so that we can extend the publish process from within publish.proj itself. publish.proj has a target, AfterWebPublish, which will be executed after each project is executed. Let’s see how this works.</p> <p>We can execute the publish process with the command below.</p><pre class="brush: xml;">msbuild .\build\publish.proj /p:VisualStudioVersion=11.0 </pre> <p>After executing this command the tail end of the result is shown in the image below.</p> <p><a href="/content/binary/WindowsLiveWriter/Howtoextendthewebpublishprocesswithoutmo_9E9F/image_2.png"><img title="image" style="border-top: 0px; border-right: 0px; border-bottom: 0px; border-left: 0px; display: inline" border="0" alt="image" src="/content/binary/WindowsLiveWriter/Howtoextendthewebpublishprocesswithoutmo_9E9F/image_thumb.png" width="893" height="463"></a> </p> <p>In the image above you can see that the MyOtherSite project is being publish to the specified location in publish.proj and the AfterWebPublish target is executed as well.</p> <p>&nbsp;</p> <p>In this post we’ve seen how we can use an MSBuild file as a publish profile, and how to extend the publish process using that same file.</p> <p>You can download the samples at <a title="https://dl.dropboxusercontent.com/u/40134810/blog/publish-injection.zip" href="https://dl.dropboxusercontent.com/u/40134810/blog/publish-injection.zip">https://dl.dropboxusercontent.com/u/40134810/blog/publish-injection.zip</a>. You can find the latest version in my <a href="https://github.com/sayedihashimi/publish-samples">publish-samples</a> repository at <a href="https://github.com/sayedihashimi/publish-samples/tree/master/publish-injection">publish-injection</a>.</p> <p>Sayed Ibrahim Hashimi | <a href="http://msbuildbook.com">http://msbuildbook.com</a> | <a href="https://twitter.com/sayedihashimi">@SayedIHashimi</a></p></div>https://sedodream.com/2013/09/21/how-to-extend-the-web-publish-process-without-modifying-project-contents/comments#comments-startMSBuildVisual StudioVisual Studio 2012webWeb Publishing Pipelinehttps://sedodream.com/feed/trackback/40b8a140-f4d8-4780-844e-60973db5c68ahttps://sedodream.com/feed/pingbackhttps://sedodream.com/post/40b8a140-f4d8-4780-844e-60973db5c68ahttps://sedodream.com/2013/06/08/introducing-vsixcompressa-nuget-package-to-compress-your-visual-studio-package/comments#comments-starthttps://sedodream.com/feed/rss/comments/40b8a140-f4d8-4780-844e-60973db5c68aIntroducing VsixCompress–a NuGet package to compress your Visual Studio Packagehttps://sedodream.com/post/40b8a140-f4d8-4780-844e-60973db5c68ahttps://sedodream.com/2013/06/08/introducing-vsixcompressa-nuget-package-to-compress-your-visual-studio-packageSat, 08 Jun 2013 00:42:57 GMT<div><p>A few weeks ago I <a href="http://sedodream.com/2013/05/13/HowToCompressAVisualStudioExtensionVSIXDuringBuild.aspx">blogged about a Visual Studio extension</a>, <a href="http://visualstudiogallery.msdn.microsoft.com/33b0242d-7158-4d39-9a01-0a08cf7c28bd">Farticus</a>, which I’m working on with <a href="http://madskristensen.net">Mads Kristensen</a>. In that post I described how the default compression of a .vsix (<em>the artifact that is created for a Visual Studio Package</em>) is not as small as it could be. It’s better to get a fully compressed VSIX because when users install the component the download time can be significantly reduced. In that post I described how you could use the <a href="http://www.msbuildextensionpack.com/help/4.0.5.0/html/f2118b59-554e-d745-5859-126a82b1df81.htm">Zip task</a> from the <a href="http://msbuildextensionpack.codeplex.com/">MSBuild Extension Pack</a> to have a fully compressed .vsix file. I will now show you how I’ve simplified this.</p><a href="https://nuget.org/packages/VsixCompress/1.0.0.4"> <p><img alt="Icon for package VsixCompress" src="http://msbuildbook.com/images/vsix-compress.png"><font size="7">VsixCompress</font></p></a> <p>Since my previous post I’ve created a NuGet package, <a href="https://nuget.org/packages/VsixCompress/1.0.0.4">VsixCompress</a> which simplifies this greatly. If you have an existing Visual Studio package and want to have a fully compressed .vsix file then all you need to do is install the <a href="https://nuget.org/packages/VsixCompress/1.0.0.4">VsixCompress</a> package.</p> <p><a href="/content/binary/Windows-Live-Writer/Introducing-VsixCompress_F242/image_2.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="/content/binary/Windows-Live-Writer/Introducing-VsixCompress_F242/image_thumb.png" width="728" height="75"></a></p> <p>&nbsp;</p> <p>After you install this package the following happens.</p> <ol> <li>NuGet package is downloaded and installed to the packages folder</li> <li>The project is edited to include an import for a new .targets file</li> <li>The build process is extended to compress the .vsix file automatically</li></ol> <p>After installing this package once you build the generated .vsix is much smaller than before. In the default case where you select to create a new C# VS Package the created .vsix is 17kb. After adding VsixCompress the resulting .vsix is only 9kb. That’s almost half the size. That’s all you need to know for local development. If you have a build server setup then there are a couple of additional steps. Let’s go over those now.</p> <h3>Build Server Support</h3> <p>I have blogged before about issues of shipping build updates in NuGet. To briefly summarize, when leveraging <a href="http://docs.nuget.org/docs/workflows/using-nuget-without-committing-packages">NuGet Package Restore</a> you have to be careful if any of those NuGet packages have build updates. When using Package Restore the NuGet packages which contain the imported .targets file(s) are restored after the build starts. What this means is that the .targets files will never be imported (<em>or an old copy is imported in the case the file exists from a previous build</em>). The only way to work around this is to restore the packages before the .sln/.csproj file themselves are built. You can read the full details at <a href="http://sedodream.com/2012/12/24/SlowCheetahBuildServerSupportUpdated.aspx">http://sedodream.com/2012/12/24/SlowCheetahBuildServerSupportUpdated.aspx</a>. I have a NuGet package, <a href="https://nuget.org/packages/PackageRestore/">PackageRestore</a>, which can help here. Take a look at my previous post <a href="http://sedodream.com/2013/06/06/HowToSimplifyShippingBuildUpdatesInANuGetPackage.aspx"><strong>How to simplify shipping build updates in a NuGet package</strong></a>. Now that we’ve discussed all the details that you need let’s discuss what my plans are going forward with this.</p> <h3>Plans going forward</h3> <p>I’m hoping to add the following features over the course of the next few weeks.</p> <ul> <li><a href="https://github.com/sayedihashimi/vsix-compress/issues/3">Automatically bump version number when building in VS</a></li> <li><a href="https://github.com/sayedihashimi/vsix-compress/issues/1">Add an option to accept the compression level as an MSBuild property</a></li> <li><a href="https://github.com/sayedihashimi/vsix-compress/issues/2">Add an option to opt in/out of compressing the VSIX as an MSBuild property</a></li></ul> <p>FYI VsixCompress is open source so you can take a look at the code, or better yet contribute at <a href="https://github.com/sayedihashimi/vsix-compress">https://github.com/sayedihashimi/vsix-compress</a>.</p> <p>Please let me know what you think of this!</p> <p>Sayed Ibrahim Hashimi | <a href="http://msbuildbook.com">http://msbuildbook.com</a> | <a href="https://twitter.com/sayedihashimi">@SayedIHashimi</a></p></div>https://sedodream.com/2013/06/08/introducing-vsixcompressa-nuget-package-to-compress-your-visual-studio-package/comments#comments-startExtensibilityVisual StudioVSIX