tag:blogger.com,1999:blog-49857626767229072622024-03-06T07:48:46.418+01:00Thoughts of Marcus- Random ramblings of a BizTalk architectRamblings, thoughts and experiences from the life as a BizTalk architect (as well as everything else I catch sight of).Unknownnoreply@blogger.comBlogger77125tag:blogger.com,1999:blog-4985762676722907262.post-57806543637635115342017-11-01T10:48:00.001+01:002017-11-01T10:48:33.373+01:00Collect MSDTC trace logs, access deniedDuring a support case, I needed to collect MSDTC trace logs. However, I ran into the issue of not having access to the c:\windows\system32\msdtc folder.<br />
<br />
The way to access this folder and the trace files collected, is to do it via an elevated command prompt. Running cmd as administrator will give you access to the folder and allow you to copy the needed trace files.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4985762676722907262.post-67683276166207782692017-10-13T10:03:00.000+02:002017-10-13T14:14:00.083+02:00Bulk modify items in Visual Studio Team Services<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
I just had a need to
add around 500 work items for a new project in Visual Studio Team Services. We
use VSTS for keeping track in our projects and use the Scrum template. In this
case, it was a bit different from a normal project since 98% of the work items
were defined before hand and most of the priority was also set. I had a list of
all the work items and needed to populate the scrum board with these in a quick
way. Still, what I learned can be very useful in other projects as well, but helped me tremendously in this case.</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
I have heard about
the export/import functionality to Excel earlier, but were curious on how to do
it in VSTS today. The documentation found online was a bit off and didn't quite tell me what I wanted. Most pages and articles found pointed me to old versions of TFS and Visual Studio. This post is for me (and others) to use as
a reference in the future.</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
Start out by
creating a custom query in VSTS that return all objects you want in a tree view format. In my case I want absolutely everything, but you could always filter out specifics to work with if you'd like.</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJGBzANWx7iIXUxGY0qNtjYHR5aS9fn_xD2M8m8c32O1gJF-S_8CA5Pe5rmC0DL_Wv2fdBNHKmsJFfhl9WvhZQ-SAXuWmNMw2utXJzF7ZVWO0CECR-gOqp35Z2YsqlaG8VFrV5eAzJF09j/s1600/snip_20171013092807.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="542" data-original-width="1082" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJGBzANWx7iIXUxGY0qNtjYHR5aS9fn_xD2M8m8c32O1gJF-S_8CA5Pe5rmC0DL_Wv2fdBNHKmsJFfhl9WvhZQ-SAXuWmNMw2utXJzF7ZVWO0CECR-gOqp35Z2YsqlaG8VFrV5eAzJF09j/s640/snip_20171013092807.png" width="640" /></a></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<span style="font-size: 11pt;">Then make sure to
enable the Team ribbon add-in in Excel. I had several versions installed (most likely
due to multiple installations of Visual Studio) so I enabled the one with the
highest version number.</span><br />
<span style="font-size: 11pt;"><br /></span>
<span style="font-size: 11pt;">Go to Options and then Add-ins in the left menu bar. At the bottom you'll find a drop-down where you can select COM Add-ins, then click Go.</span></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjU9MAMt8YVmpN9wd95bW_W0p5KCquQ0CLVgOLmOPcObb_XcrrGSTgbPURwf3QhZW9UFTHKkd-P9lBNuqEJlbul6stOLmeojuYi-Y-UaDmzzPIve1_ipMmrmPnIMb1_e5yaeywvyygtjQ4l/s1600/snip_20171013092921.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="678" data-original-width="826" height="523" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjU9MAMt8YVmpN9wd95bW_W0p5KCquQ0CLVgOLmOPcObb_XcrrGSTgbPURwf3QhZW9UFTHKkd-P9lBNuqEJlbul6stOLmeojuYi-Y-UaDmzzPIve1_ipMmrmPnIMb1_e5yaeywvyygtjQ4l/s640/snip_20171013092921.png" width="640" /></a></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisJeaj6NRGXk6U8x5fJxEJQUqM9XJSv6Xd3NL41StQvtgpR45xSqMJwXOV4rRbk93xaa5mhTwbm6v7-uW1NWLiIWBxFRcOpVDK5kQczyYy3-RqGlqYv9XhZBIzaGfBd47oawAmrWuQfg8k/s1600/snip_20171013092852.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="259" data-original-width="607" height="272" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisJeaj6NRGXk6U8x5fJxEJQUqM9XJSv6Xd3NL41StQvtgpR45xSqMJwXOV4rRbk93xaa5mhTwbm6v7-uW1NWLiIWBxFRcOpVDK5kQczyYy3-RqGlqYv9XhZBIzaGfBd47oawAmrWuQfg8k/s640/snip_20171013092852.png" width="640" /></a></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br />
If you don't have the Team Foundation Add-in in the list, you can get it by either installing Visual Studio or install the Team Foundation Server Office Integration from <a href="https://www.visualstudio.com/downloads/#team-foundation-server-office-integration-2015-update-3-1" target="_blank">here</a> (a bit down in the downloads list).</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
Then create
a new Excel book and connect to VSTS via the newly enabled Team ribbon by s<span style="font-size: 11pt;">electing New List and
connect to the VSTS and then select the new "All items" query.</span></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
Add those columns you are interested in. In my case it was Remaining Work and Effort, since I already had those numbers.</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDyf128Y8kczGLDppXsxajLFN4lbHGjAX7w57399tfJViRmwuVrE5pVwRGq97iaVmk84KogipRn9ohpZZuVDbgJq13rCKSwpFkQ8eb_ih_ClGRqtzeAmtDU8UPsdq8c2K6-9DQpwRyuJag/s1600/snip_20171013093343.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="337" data-original-width="1073" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDyf128Y8kczGLDppXsxajLFN4lbHGjAX7w57399tfJViRmwuVrE5pVwRGq97iaVmk84KogipRn9ohpZZuVDbgJq13rCKSwpFkQ8eb_ih_ClGRqtzeAmtDU8UPsdq8c2K6-9DQpwRyuJag/s640/snip_20171013093343.png" width="640" /></a></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
Also, in order to be able to work with items on different levels, you need to make sure that you have Title-columns that correspond to the levels. In this case, Title 1 is used for Backlog Item and I have to add a level for the Tasks. Click Add Tree Level in the ribbon and you will get a new column for Title 2 that will contain the Task title.</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDK1C91g17pC3GbzB_gGoxmjx6pOra_mRkNdBam_KFsOc89qwAupUbnfJpwrZw-WODOixXhFRvllhyphenhyphen3S4OaYmwGdATfScUGv8BaB_2W0hr7h_pzRu-Bh1Q7hwO2fUzj0iZuQKUn9oCnrlo/s1600/snip_20171013094117.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="199" data-original-width="296" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDK1C91g17pC3GbzB_gGoxmjx6pOra_mRkNdBam_KFsOc89qwAupUbnfJpwrZw-WODOixXhFRvllhyphenhyphen3S4OaYmwGdATfScUGv8BaB_2W0hr7h_pzRu-Bh1Q7hwO2fUzj0iZuQKUn9oCnrlo/s1600/snip_20171013094117.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSM1g251dSCVBlHpms3fNRQgTcGAXuUHRSEew_IU6GlincRgZ6ri3bDxve8xEGdCXQtGLQeE6xX5H2OwY-wk5uInBGmNG2OFBDWqAi4IBgqbSsi2ZD91Fb9DRA9vGQ82FuB_7ykdCysCWh/s1600/snip_20171013100005.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="127" data-original-width="1477" height="52" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSM1g251dSCVBlHpms3fNRQgTcGAXuUHRSEew_IU6GlincRgZ6ri3bDxve8xEGdCXQtGLQeE6xX5H2OwY-wk5uInBGmNG2OFBDWqAi4IBgqbSsi2ZD91Fb9DRA9vGQ82FuB_7ykdCysCWh/s640/snip_20171013100005.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
Then start
to populate the table in a normal Excel way. Don't miss out on utilizing the
filtering functionality in the table to quickly select items and set properties
on those. One example is to filter out everything with "deploy" in
the title and set the Activity property to Deployment by using Drag-and-fill. This is WAY faster than doing it in the web GUI, even if you there can select and edit multiple items at once.</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgo9HEkGqYjCTJahKpeWd_xuWUZMTaKHhCoYltwxuttMBheHA1yZVcEWk-7-bPRQq21rmwlaT5H2b4CK9Y1ixH-tgFXb6pGh2wIO4X697YaaTs2-nODiSM5EHYTUVyU-xSl_myd9CeyQJul/s1600/snip_20171013093904.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="226" data-original-width="1469" height="97" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgo9HEkGqYjCTJahKpeWd_xuWUZMTaKHhCoYltwxuttMBheHA1yZVcEWk-7-bPRQq21rmwlaT5H2b4CK9Y1ixH-tgFXb6pGh2wIO4X697YaaTs2-nODiSM5EHYTUVyU-xSl_myd9CeyQJul/s640/snip_20171013093904.png" width="640" /></a></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
Then it is just a
matter of Publishing to VSTS to populate the board with the items. So click Publish in the ribbon.</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnyhoKTOE5gvdStZvlplpXhqChIlL8abRu-Ek6nO-9tw-ONUNs3HRWLJn1GaJQEoOB90cpWpmLy0bNyil75Kspm3nHlwcovF6qczMDzItwNn0_4yhr-gav9_RVgoUFx-PETQoC5Mhcl3hR/s1600/snip_20171013093917.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="192" data-original-width="322" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnyhoKTOE5gvdStZvlplpXhqChIlL8abRu-Ek6nO-9tw-ONUNs3HRWLJn1GaJQEoOB90cpWpmLy0bNyil75Kspm3nHlwcovF6qczMDzItwNn0_4yhr-gav9_RVgoUFx-PETQoC5Mhcl3hR/s1600/snip_20171013093917.png" /></a></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
Jump over to VSTS and refresh the page to get your updated backlog.</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaU28tPBSex38efxQjYTbAdZgeQNLEIbMJfaIJWfqto7O07Le2A-mYEu8LCmX1QtiwNULAkciSvaXCP3uN-JiZpdfoWoh_kGMYCVKAJwdCOYR-00uB5C7LqDRZa3dyLGvlLSo_6y6G1Kxj/s1600/snip_20171013094158.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="436" data-original-width="1097" height="251" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaU28tPBSex38efxQjYTbAdZgeQNLEIbMJfaIJWfqto7O07Le2A-mYEu8LCmX1QtiwNULAkciSvaXCP3uN-JiZpdfoWoh_kGMYCVKAJwdCOYR-00uB5C7LqDRZa3dyLGvlLSo_6y6G1Kxj/s640/snip_20171013094158.png" width="640" /></a></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
Just be vary of others updating the board while you work. Changes may be overwritten and/or messed up.</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4985762676722907262.post-67425800794245376232017-09-26T13:31:00.003+02:002017-09-26T13:31:55.669+02:00Getting notifications from a mouse trap using RuuviTag, Raspberry Pi 3, Windows IoT Core (and a string)I was part of a Kickstarter campaign that ended up with me receiving five <a href="https://tag.ruuvi.com/" target="_blank">RuuviTags</a>. They are small battery powered tags that communicate via Bluetooth Low Energy (BLE) and are equipped with a sensor chip. They are of course extendible and can be flashed with custom firmware. All in all, fun toys to tinker with when time permits.<br />
<div>
<br /></div>
<div>
Since I have a few mouse traps scattered around the house in locations that I rarely visit, I'd like to get a notification when one of them has trapped a mouse. Since the RuuviTag has acceleration data as part of the data available from the sensors (the other are temperature, atmospheric pressure, humidity and battery voltage), I thought this could be used to check whether a mouse trap has been active or not.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe width="320" height="266" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/bPCZY0jCXmI/0.jpg" src="https://www.youtube.com/embed/bPCZY0jCXmI?feature=player_embedded" frameborder="0" allowfullscreen></iframe></div>
<br />
<br /></div>
<div>
My basic setup is this:</div>
<div>
A mouse trap with the RuuviTag attached. This is using stock Ruuvi firmware in RAW mode. This means that it at 1Hz interval will broadcast 20 bytes of raw sensor data via bluetooth. I have a Raspberry Pi 3 running Windows IoT Core in my house that will intercept the signal. When a change in the acceleration data is identified, it is interpreted as the mouse trap has been activated (or flipped over or in any way tampered with). If so, a REST call is made to <a href="https://pushover.net/api" target="_blank">Pushover </a>that in turn will send a notification to my cell phone. I already use Pushover for other notifications in my home such as notifying me that tool batteries are fully loaded, that the car heater hasn't been switched off (if for instance it has been activated in the morning, but we never took the car to work) etc.</div>
<div>
<br /></div>
<div>
Now, one could argue that the sensor should be able to itself identify a change in the acceleration data and then send a notification regarding this instead of offloading the processing to the RPi3. However, since the tags, while having extremely good bluetooth range, can be missed by the RPi3, the current setup will ensure that I always catch a change in acceleration data. Even if I miss out on five transmits from the tag directly after a change in acceleration data, the sixth transmit will differ from the last one received, and hence trigger the logic.</div>
<div>
<br /></div>
<div>
I will however look into turning down the transmit interval since 1Hz is quite often for this need. I guess I can prolong the battery life a bit by doing so.</div>
<div>
<br /></div>
<div>
On the plus side, since I have at least one tag in the garage, I can utilize the other data sent by the tag. The temperature can be used as input to the car heater logic so that the time for the car heater will differ depending on the temperature inside the garage. Right now, I use outdoor temperature, but since the car is inside, it is not 100% correct for optimizing performance/cost.</div>
<div>
<br /></div>
<div>
The code is not advanced at all. I briefly looked into pairing, GATT profiles and other stuff before realizing that I didn't need any of that.</div>
<div>
<br /></div>
<div>
I simply add a <a href="https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothleadvertisementwatcher" target="_blank">BluetoothLEAdvertisementWatcher </a>to catch any BLE signals received.</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">BluetoothLEAdvertisementWatcher watcher = new BluetoothLEAdvertisementWatcher();</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">watcher.Received += OnAdvertisementReceived;</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">watcher.Start();</span></div>
</div>
<div>
<br /></div>
<div>
I also have a small class to hold info regarding my tags and the received data.</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">bleTags.Add(new BLETag { BTAddress = 230418796132391, IDNumber = 5, Name = "Mouse trap garage" });</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">bleTags.Add(new BLETag { BTAddress = 241760085512663, IDNumber = 4, Name = "Mouse trap garage #2" });</span></div>
</div>
<div>
<br /></div>
<div>
Then in my OnAdvertisementReceived event, I check the tags in my class against the received BTAddress to see if the advertisement is for a tag I have interest in (there are quite a lot of bluetooth traffic in my house).</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">bleTags.FindIndex(x => x.BTAddress.Equals(eventArgs.BluetoothAddress));</span></div>
<div>
<br /></div>
<div>
Then I need to get the second data section from the advertisement since that is where the raw sensor data is stored.</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">BluetoothLEAdvertisementDataSection BLEDataSection2 = eventArgs.Advertisement.DataSections[1];</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">var dataReader = DataReader.FromBuffer(BLEDataSection2.Data);</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">byte[] fileContent = new byte[dataReader.UnconsumedBufferLength];</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">dataReader.ReadBytes(fileContent);</span></div>
</div>
<div>
<br /></div>
<div>
The data string is then parsed byte by byte <a href="https://github.com/ruuvi/ruuvi-sensor-protocols" target="_blank">according to the specification</a> to get each sensor value.</div>
<div>
<br /></div>
<div>
To check if the orientation has changed, I currently just check if any of the acceleration values has changed more than 200mG, which will give me enough slack to not trigger on normal sensor fluctuation, but catch any movement from the sensor.</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">public bool OrientationHasChanged()</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">{</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><span style="white-space: pre;"> </span>bool retval = false;</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><span style="white-space: pre;"> </span>if (PreviousSensorData != null)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><span style="white-space: pre;"> </span>{</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><span style="white-space: pre;"> </span>double xdiff = Math.Abs(PreviousSensorData.AccelerationX - SensorData.AccelerationX);</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><span style="white-space: pre;"> </span>double ydiff = Math.Abs(PreviousSensorData.AccelerationY - SensorData.AccelerationY);</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><span style="white-space: pre;"> </span>double zdiff = Math.Abs(PreviousSensorData.AccelerationZ - SensorData.AccelerationZ);</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><span style="white-space: pre;"> </span>double difflimit = 200; // breaking limit in mG</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><span style="white-space: pre;"> </span>if (xdiff > difflimit || ydiff > difflimit || zdiff > difflimit)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><span style="white-space: pre;"> </span>retval = true;</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><span style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><span style="white-space: pre;"> </span>return retval;</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">}</span></div>
</div>
<div>
<br /></div>
<div>
The sensor in turn is currently fastened to a spring loaded arm on the mouse trap using a string so that when the mouse trap is moved ever so slightly or that it is triggered, the tag will move enough to change the acceleration data more than the 200mG needed to indicate a change.</div>
<div>
<br /></div>
<div>
When testing it out, it has showed to work very well. From a mouse meeting its creator to me getting a push notification, it is 1-5 seconds. This due to the sensor broadcasting at 1Hz, not all advertisements getting to the RPi and finally the push notification that has to make it around the world and back to my phone.</div>
<div>
<br /></div>
<div>
The code is most likely going to change. Altering the filtering of advertisements, trying to increase the quality of transmissions so that none are dropped and similar things are in the pipeline.</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4985762676722907262.post-2363618721694190712015-12-08T21:39:00.001+01:002015-12-08T21:39:55.217+01:00Using the XMLTransmit pipeline to write your own custom XML declarationA <a href="https://social.msdn.microsoft.com/Forums/en-US/2e79de01-f7d4-43fc-b671-ad079ebccb15/standaloneyes-in-out-xml-document" target="_blank">question in the MSDN BizTalk Forums</a> caught my eye a few days ago. It was about wanting to set the attribute standalone="yes" in the XML declaration on an outbound message.<br />
<br />
I have never had the need to set this attribute before, so wasn't sure of whether the map properties or any other setting could make it be written. The other responses in the thread told be that it couldn't. It was then I thought of an old post I wrote regarding <a href="http://thoughtsofmarcus.blogspot.se/2010/02/adding-xml-stylesheet-reference-or.html" target="_blank">using the XMLTransmit pipeline properties to write an xml-stylesheet reference to a message</a>. This surely had to be able to write a custom XML declaration instead. And it did.<br />
<br />
What you basically do is set the property <i>AddXmlDeclaration</i> to <i>false</i>, and then write your full custom XML declaration in the property XmlAsmProcessingInstructions. This will write out your custom string as the XML declaration. Or in reality, it will not write it as the declaration, but since we omit the real one, it will take the place of it.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpM4_u9tTBih6ly5Pj2U0bqAevahj7JSfIrSLi9IhgAtl9ejZPV-Fx_V44nJ4Sm8pC6OXNBjD5Skmksr6lC7R0MlbwU2sLON6W7_gGNRX9gjDu3Tm9cVlCEQ_RUi1IsAYRibxbSQxwP9mR/s1600/XMLTransmitPipelineStandaloneYes.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpM4_u9tTBih6ly5Pj2U0bqAevahj7JSfIrSLi9IhgAtl9ejZPV-Fx_V44nJ4Sm8pC6OXNBjD5Skmksr6lC7R0MlbwU2sLON6W7_gGNRX9gjDu3Tm9cVlCEQ_RUi1IsAYRibxbSQxwP9mR/s1600/XMLTransmitPipelineStandaloneYes.png" /></a></div>
<br />
<br />
Just make sure to have the other properties correctly set (the charset) or it might not match the document itself which may or may not cause havok in the receiving end.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4985762676722907262.post-27901534985519822562015-10-09T15:57:00.002+02:002015-10-09T15:57:36.645+02:00Faster filtering in PowerShell than using Where-ObjectIn a project I'm using a PowerShell script to read in a lot of .csv files and then do some lookups between these in order to get the wanted output. This all works well, but has been a bit slow lately due to a lot more data in the files.<br />
<br />
I narrowed the speed issue down to a few lines where I iterate over some files in order to find a few rows that I need. Basically, the Where-Object cmdlet is the culprit.<br />
<br />
A simplified example is below:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">$mycsvfile = Import-Csv .\mydata.csv</span><br />
<span style="font-family: Courier New, Courier, monospace;">$dataiwant = $mycsvfile | Where-Object {$_.idno -eq 5}</span><br />
<br />
I had a few similar lines in the script, making the time to select the data add upp to 9 seconds, which was far to long in this case.<br />
<br />
I found <a href="http://powershell.org/wp/2013/11/17/powershell-performance-filtering-collections/" target="_blank">this post</a> that show a few variants on filtering collections, and by simply using the PS v4 .Where() notation to do the same thing, I could bring this down to a single second.<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">$mycsvfile = Import-Csv .\mydata.csv</span><br />
<span style="font-family: Courier New, Courier, monospace;">$dataiwant = $mycsvfile.Where({$_.idno -eq 5})</span><br />
<br />
So lesson learned: PowerShell is evolving quickly and what I thought was a nice way to do something might very well be just fine, but there might also be a quicker way just around the corner. In this example, I'm sacrificing the streaming capabilities, but gain a lot of performance, just by changing a few characters.Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-4985762676722907262.post-57553443002454447052015-09-29T18:32:00.000+02:002015-10-09T15:57:59.347+02:00XSD in Visual Studio and the warning message "Request for the permission of type 'System.Security.Permissions.FileIOPermission"When working in a project in Visual Studio that had a schema repository added, the warning message "Request for the permission of type 'System.Security.Permissions.FileIOPermission" showed up in various places where I had schema imports. The warning did not show up everywhere though and the project built just fine.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEht8UFCfBxKQxpxWBvPaqs-W_nVRUBMXxpfropquLx7I7964V9Vxdl0ZykzvDISO7Yguvo_4EDE-Rq8mF_YfAW7AUx5JUDnpD4qpq4rLjg39WR8uAlQH_a8U7HEFo4y9e4QkcTBd9h1zxSp/s1600/XsdFileIOPermissionError1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="72" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEht8UFCfBxKQxpxWBvPaqs-W_nVRUBMXxpfropquLx7I7964V9Vxdl0ZykzvDISO7Yguvo_4EDE-Rq8mF_YfAW7AUx5JUDnpD4qpq4rLjg39WR8uAlQH_a8U7HEFo4y9e4QkcTBd9h1zxSp/s640/XsdFileIOPermissionError1.png" width="640" /></a></div>
<br />
It turned out that the reason was that some of the xsd files where downloaded or copied from a network share and were therefore blocked in Windows, leading up to the warning message.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglQ82rHQpfYdzASw6oBqOZnH_ajJ_jibrEM4KJRvVE7Kz8DQNxV2uJymKVSpjsLrRXnm2qCV1GECXZ6rbYDHHzil8eMljZJykK46kW9zQJ9oQP64ls0VRxeoE9loa2lS_GxXpLNtP8FP1c/s1600/XsdFileIOPermissionError2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglQ82rHQpfYdzASw6oBqOZnH_ajJ_jibrEM4KJRvVE7Kz8DQNxV2uJymKVSpjsLrRXnm2qCV1GECXZ6rbYDHHzil8eMljZJykK46kW9zQJ9oQP64ls0VRxeoE9loa2lS_GxXpLNtP8FP1c/s400/XsdFileIOPermissionError2.png" width="291" /></a></div>
<br />
The warnings could be removed by simply unblocking the offending files, and restarting Visual Studio.<br />
<br />
This also lead me to the quick way to unblock a lot of files at once. Simply use PowerShell to iterate over the files and use the <a href="https://technet.microsoft.com/en-us/library/hh849924.aspx" target="_blank">Unblock-File</a> cmdlet:<br />
<span style="font-family: Courier New, Courier, monospace;">gci -r | Unblock-File</span>Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-4985762676722907262.post-86504683701896373472014-11-04T08:23:00.000+01:002014-11-05T07:28:36.327+01:00Raspberry Pi, kill the tvservice if you are not using HDMII'm running a Raspberry Pi at home for various tasks and access it remotely using SSH for all maintanence tasks. This means that the HDMI control in the Pi is unused and hence can be switched off for maybe not better performance, but at least for a lower working temperature.<br />
<br />
When logged in, you can switch the HDMI off by running<br />
<span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;">tvservice -o</span></span><br />
<br />
However, this will reset at boot time. So one way to handle this is to simply add the command to the boot scripts.<br />
<br />
I did it the quick way by adding the command to the boot sequence:<br />
<span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;">vi /etc/init.d/customboot.sh</span></span><br />
<br />
Add<br />
<span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;">### BEGIN INIT INFO<br /># Provides: customboot<br /># Required-Start: networking<br /># Required-Stop: networking<br /># Default-Start: 2 3 4 5<br /># Default-Stop: 0 1 6<br /># Short-Description: Custom boot commands<br /># Description: Custom boot commands<br />### END INIT INFO</span></span><br />
<span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;">echo "Turning off tvservice" </span></span><br />
<span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;">/opt/vc/bin/tvservice -o</span></span><br />
<br />
Then add permissions and add the script to the boot sequence<br />
<span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;">sudo chmod +x /etc/init.d/customboot.sh<br />sudo update-rc.d customboot.sh defaults</span></span><br />
<br />
By doing this, I lowered the idle temperature of my Pi with about two degrees C:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7OwKlPi0y-V4VA-hx5ibEwHJSat9D2dtW5ZNhlVqPTgCuqczbsAThp1Ft_XnaRsJ3nXGZUN5k34Qwt3V0Jdjfr5Y1vicGyWXqyGWbwApQG8JKvxGlrHv7CzH81yQ4N9rx0Z4wCPu_jZzW/s1600/RPi_CPU_chart.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7OwKlPi0y-V4VA-hx5ibEwHJSat9D2dtW5ZNhlVqPTgCuqczbsAThp1Ft_XnaRsJ3nXGZUN5k34Qwt3V0Jdjfr5Y1vicGyWXqyGWbwApQG8JKvxGlrHv7CzH81yQ4N9rx0Z4wCPu_jZzW/s1600/RPi_CPU_chart.png" height="200" width="400" /></a></div>
<br />Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4985762676722907262.post-45925857676486598882014-07-03T07:48:00.000+02:002014-07-03T07:48:00.100+02:00Slow performance in PowerShell Get-ChildItem over UNC pathsI got a ticket submitted to me that proved to be quite interesting. The basics where that a specific maintenance script were running for ages on a server causing some issues.<br />
<br />
The script itself was quite simple, it did a recursive gci on a path and performed an action on each item matching a where clause that identified empty folders. Nothing wrong there. However, even if the specified path contained a massive amount of folders and files, it still shouldn't have been running for days (literally) causing the ticket to be created.<br />
<br />
When looking into the matter, I found <a href="http://blogs.msdn.com/b/powershell/archive/2009/11/04/why-is-get-childitem-so-slow.aspx" target="_blank">this blog post on the Windows PowerShell blog</a> that goes into detail why Get-ChildItem has slow performance at times. The main culprit is the .NET APIs that is too chatty and causes a lot of overhead traffic over the network when trying to query for files. This was fixed in PowerShell 3.0 that uses new API:s.<br />
<br />
A quick test using a folder with 700 subfolders and a total of 40 000 files where I execute the script line<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">(gci d:\temp -Recurse | where-object {$_.PSIsContainer}) | Where-object {($_.GetFiles().Count + $_.GetDirectories().Count) -eq 0} | out-file d:\dir.txt</span> <br />
<br />
reveals the following execution time numbers:<br />
<br />
Using <b>PowerShell 2.0</b> and accessing the path as an <b>UNC</b>: <span style="color: #cc0000;"><b>100s</b></span><br />
Using <b>PowerShell 3.0</b> and accessing the path as an <b>UNC</b>: <span style="color: #e69138;"><b>33s</b></span><br />
Using <b>PowerShell 2.0</b> and accessing the path <b>locally</b>: <span style="color: #38761d;"><b>6s </b></span><br />
Using <b>PowerShell 3.0</b> and accessing the path <b>locally</b>: <span style="color: #38761d;"><b>5s</b></span><br />
<br />
In my case, the server was both running PowerShell 2.0 and accessing the path as an UNC causing a major performance hit. The solution is simply to both run the script locally on the server where the task has to be performed as well as upgrading to at least PowerShell version 3.0. As can be seen from my quick test, the best performance gain is clearly to run the script locally giving about 17 times better performance.<br />
<br />
While no rocket science that accessing tons of files locally has to be faster then doing it over the network, it is still fairly common to see scripts executed on application servers and performing tasks on file shares.<br />
<br />
This also proves that it is important in our business to stay on top of new versions of tools and frameworks in order to catch these types of improvements. I can be certain that there is quite a number of people out there bashing gci heavily for it's slow performance when in fact it has improved a lot between PowerShell 2.0 and 3.0.Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-4985762676722907262.post-90607754157464149582014-06-24T17:59:00.000+02:002014-06-24T17:59:49.502+02:00Base64 encode/decode part of messages in map - part 2Back in November I wrote a post about <a href="http://thoughtsofmarcus.blogspot.se/2013/11/base64-encodedecode-part-of-messages-in.html" target="_blank">encoding messages as base64 strings in a BizTalk map</a>. I never added the explicit implementation of how to decode the message though. However, I was asked to provide an example of it, so here is part 2: how to decode a base64 string from an XML message and output it in BizTalk.<br />
<br />
Consider the scenario to be the opposite of what we did in part 1.<br />
<br />
We have a message on the input side that has two fields, one with an id as a string, and another string element that holds the entire base64 encoded string.<br />
<br />
<span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"><ns0:Root xmlns:ns0="http://BizTalk_Server_Project6.Schema1"><br /> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><</span>SomeId</span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;">></span>1</span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><</span>/SomeId</span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;">></span> <br /> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><</span>EncodedData>PG5zMDpSb290IHhtbG5zOm5zMD0iaHR0cDovL0JpelRhbGtfU2VydmVyX1Byb2plY3Q2LlNjaGVtYTIiPg0KICA8RGF0YT5EYXRhXzA8L0RhdGE+IA0KICA8RGF0YTI+RGF0YTJfMDwvRGF0YTI+IA0KPC9uczA6Um9vdD4=</span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><</span>/EncodedData</span><span style="font-family: "Courier New",Courier,monospace;">></span></span><br />
<span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><</span>/ns0:Root</span></span><span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">></span></span> </span></span><br />
<br />
On the output side, we want to have a message that conforms to the schema we have defined. The message is the entire contents of the base64 encoded string in the input.<br />
<br />
If we parse the encoded string, we get:<br />
<span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"><ns0:Root xmlns:ns0="http://BizTalk_Server_Project6.Schema2"><br /> </span></span><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"><</span></span>Data>Data_0</span></span><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"><</span></span>/Data> <br /> </span></span><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"><</span></span>Data2>Data2_0</span></span><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"><</span></span>/Data2></span></span><br />
<span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"><</span></span>/ns0:Root></span></span><br />
<br />
Which conforms fully to the schema defined.<br />
<br />
So, the task is to extract the contents from the EncodedData element, decode them, and use the full string as the output message. All in a single BizTalk map.<br />
<br />
The map will look like this to begin with, with the two schemas chosen:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEja-c0zNRWcqbISyoTajhun-NGt0t59n6W6bS2fwKnDYKYcOv3TChz3fsw_mCoqjgEeP0_e1fG74synwjJbbBusTwWhUwsraLL1OypSaXacDDybNqV6W8a8fheMKFJONhErPs5eZeaJRdv3/s1600/Base64DecodeInMap_Map1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEja-c0zNRWcqbISyoTajhun-NGt0t59n6W6bS2fwKnDYKYcOv3TChz3fsw_mCoqjgEeP0_e1fG74synwjJbbBusTwWhUwsraLL1OypSaXacDDybNqV6W8a8fheMKFJONhErPs5eZeaJRdv3/s1600/Base64DecodeInMap_Map1.png" /></a></div>
<br />
Similar to when we encoded, we add first a scripting functoid that has no connections, and paste the code for the decode function in it:<br />
<br />
<span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">public string Base64DecodeData(string param1)<br />{<br /> byte[] decodedBytes = Convert.FromBase64String(param1);<br /> return System.Text.UTF8Encoding.UTF8.GetString(decodedBytes);<br />}</span></span><br />
<br />
We simply take a string as an input parameter, decode this and return the decoded string back.<br />
<br />
Then we create a new scripting functoid that we set to inline Xsl and paste this code into it:<br />
<br />
<span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"><xsl:variable name="data"><br /> </span></span><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"><</span></span>xsl:value-of select="//EncodedData" /</span></span><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">></span></span><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span></span></span><br />
<span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"><</span></span>/xsl:variable</span></span><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">></span></span><br />
<span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"></span></span><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"><</span></span>xsl:value-of select="userCSharp:Base64DecodeData($data)" disable-output-escaping="yes" /</span></span><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">></span></span><br />
<br />
This functoid is connected to the output root node giving us a map that looks like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioWkZytj2dYlY8EE8kTmQL0YRGDe-spaQzN_OOIvW15JNK09Cz8tuhnjVtigZyZXQuHHJlNhseh5Oxd8ZJgXwSvgTwunGORLpOXtXWCO4Jai_A6Pag-ggrUBhNS0nMYtx8tMptpZak_g9I/s1600/Base64DecodeInMap_Map2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioWkZytj2dYlY8EE8kTmQL0YRGDe-spaQzN_OOIvW15JNK09Cz8tuhnjVtigZyZXQuHHJlNhseh5Oxd8ZJgXwSvgTwunGORLpOXtXWCO4Jai_A6Pag-ggrUBhNS0nMYtx8tMptpZak_g9I/s1600/Base64DecodeInMap_Map2.png" /></a></div>
<br />
When executing this map with the input message above, we will get the output message properly formatted.<br />
<br />
The tricks used here is two. First off, we use the same pattern as before with calling a predefined function we have in another scripting functoid in order to call a simple C# function from our XSL code. Then in the XSL, we first extract the string from our input message and store it in a variable. This is then passed into our C# function and we get a string back. However, if we do not specify the disable-output-escaping="yes" in our value-of select, we would get the string entity encoded. With this extra property set, the string will be output as it is and the way we want it.<br />
<br />
The same technique can of course easily be used to just output part of a message by simply connecting the scripting functoid to the node you want to populate (if for instance you have a schema that has a node defined as xs:any that you want to use).<br />
<br />Unknownnoreply@blogger.com5tag:blogger.com,1999:blog-4985762676722907262.post-19204127653131137142014-06-02T17:42:00.003+02:002014-06-02T17:42:55.242+02:00Error 5644 when trying to enable a SQL Server notification receive location in BizTalk ServerWhen using the SQL Server broker functionality in order to have SQL Server push notifications to BizTalk instead of polling a table, I've found that the following error is quite common to encounter.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-1UKBcd0uptMXyWIyZQ1IT84fit2zLD4SzOoDRsRvfLsYC5VhEIhYnRg7BIE9rsJtqalSRmDqHLuikzpQBJpm3SXjocpU-gmYuGdvROAy0Ccb1xQRfH12wTzOoSI2F2uELNEsPvxzkx_b/s1600/Event5644BizTalkServer.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-1UKBcd0uptMXyWIyZQ1IT84fit2zLD4SzOoDRsRvfLsYC5VhEIhYnRg7BIE9rsJtqalSRmDqHLuikzpQBJpm3SXjocpU-gmYuGdvROAy0Ccb1xQRfH12wTzOoSI2F2uELNEsPvxzkx_b/s1600/Event5644BizTalkServer.png" height="277" width="400" /></a></div>
<blockquote class="tr_bq">
<i>The Messaging Engine failed to add a receive location "Event1" with URL "mssql://localhost//EventDB" to the adapter "WCF-Custom". Reason: "Microsoft.ServiceModel.Channels.Common.TargetSystemException: The notification callback returned an error. Info=Invalid. Source=Statement. Type=Subscribe.</i><br /></blockquote>
The error message tells you that the statement entered is invalid, but not in which way. There are a lot of rules to comply with that all are available on MSDN: <a href="http://msdn.microsoft.com/en-us/library/ms181122.aspx">http://msdn.microsoft.com/en-us/library/ms181122.aspx</a> And beside the "normal" ones such as "do not use aggregate functions" and "do not use an asterisk to define the resultset", one that constantly haunts me are "table names must be qualified with two-part names", meaning that you have to prefix all tables with the schema name, such as "dbo.EventTable". Just using select blah from EventTable where processed=0 will generate the error above.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4985762676722907262.post-71917713118080498292014-05-29T11:10:00.000+02:002014-06-02T11:11:03.199+02:00SQL Server: Invalid prefix or suffix characters error messageWhen trying to do different operations in SQL Server Management Studio such as "Edit Top 200 Rows", you might get the error message "Invalid prefix or suffix characters. (MS Visual Database Tools)".<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKu8zsUwUGraAJmVAP8da4XWl2coBaqxQJ8OcNhyphenhyphenAJ-65xgNZ2BwK5Dn_WPlUI7fNUImVRaDS8ZQU5AgtlSK69ot5ahW8Clik_wF4QsmH0ic8-M3JzKoaZfGC20jJJSlH4BZyP9FIR7Obn/s1600/MSSQLInvalidPrefixOrSuffixCharacters.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKu8zsUwUGraAJmVAP8da4XWl2coBaqxQJ8OcNhyphenhyphenAJ-65xgNZ2BwK5Dn_WPlUI7fNUImVRaDS8ZQU5AgtlSK69ot5ahW8Clik_wF4QsmH0ic8-M3JzKoaZfGC20jJJSlH4BZyP9FIR7Obn/s1600/MSSQLInvalidPrefixOrSuffixCharacters.png" /></a></div>
<br />
This is most likely due to the fact that the Management Studio tool is an older version than the database you are connected to and trying to perform the operation on. For instance, using SQL Server Management Studio for SQL Server 2008R2 and connecting to a SQL Server 2012 database will render the above error message when trying to perform the "Edit Top 200 Rows" operation on a table or view.<br />
<br />
The solution is to use the same version of Management Studio as the database in question.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4985762676722907262.post-67774030046250069142014-04-04T18:53:00.001+02:002014-04-10T11:55:19.027+02:00BizTalk with codeplex SFTP adapter, doing a file move on AfterGet<br />
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
A client has a setup
with the <a href="https://sftpadapter.codeplex.com/" target="_blank">Codeplex SFTP adapter</a>, reading files from a site and then deleting
them when read using the Delete parameter in the AfterGet property within the
receive location.</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
A need arised where
the files would need to be moved to an archive folder in the SFTP site instead
of being deleted.</div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
<br /></div>
<div style="font-family: Calibri; font-size: 11.0pt; margin: 0in;">
There is no mention
of this in the documentation of the adapter, however, by checking the
underlying code one can see how we can do the move.<br />
<br />
The OnBatchComplete method located in BatchHandler.cs, will be called when a message has been sent successfully to BizTalk and hence be removed/renamed on the SFTP server. The line<br />
<br />
<span style="font-family: "Courier New",Courier,monospace; font-size: small;">string renameFileName = CommonFunctions.CombinePath(Path.GetDirectoryName(fileName), batchMessage.AfterGetFilename);</span><br />
<br />
Is the interesting part. We see that when the Rename option is chosen in the adapter properties, the CombinePath method will be called to create the new full path for the file based on the current directory where it is located, and a new filename. This can be utilized by simply setting the new filename to include a relative path as well as the filename and by doing that create a move of the file and have the rename optional. The latter since the macro replacements will be done after the creation of the full path.<br />
<br />
Suppose we read files located in <i>/home/marcus/btstest/</i> and after reading these should be moved to <i>/home/marcus/btstest/archive/</i>. In this case, you would set the AfterGet File Name property to read <i>archive/%SourceFileName%</i><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWa0Ga137LbnjNi6p4Pe-tCz07-JH0yZWztpYXezuKdCspbOrMfDIWr1-kpkpQsllypmeJlOMIy8vNeqMyRnWUGGuE7nOGCwBNYMTf4yWnw3SClnfCRD7DHrD3IcHG3E14Ts5hjTZFswh1/s1600/SFTPAdapterConfigurationForRename2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWa0Ga137LbnjNi6p4Pe-tCz07-JH0yZWztpYXezuKdCspbOrMfDIWr1-kpkpQsllypmeJlOMIy8vNeqMyRnWUGGuE7nOGCwBNYMTf4yWnw3SClnfCRD7DHrD3IcHG3E14Ts5hjTZFswh1/s1600/SFTPAdapterConfigurationForRename2.png" height="400" width="358" /></a></div>
<br />
If you instead want to move the files to a directory outside of your current path, you can do so by specifying the parent by the usual two dots (..) like for instance <i>../btstestarchive/%SourceFileName%</i> for the directory located at <i>/home/marcus/btstestarchive/</i>. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhj5IauCAjyHliJaHWJQOInGts6uK90XToohynrAnCK7LRc9aY4EPDVac8c9XJlgt-QSkX_-M-YXMWDgiUyQJ_CxrxJS14fB0b4DB4CwKqvU3HNcATg-W_Ww6h1Grz2GUiECh5LBLPIxhYl/s1600/SFTPAdapterConfigurationForRename1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhj5IauCAjyHliJaHWJQOInGts6uK90XToohynrAnCK7LRc9aY4EPDVac8c9XJlgt-QSkX_-M-YXMWDgiUyQJ_CxrxJS14fB0b4DB4CwKqvU3HNcATg-W_Ww6h1Grz2GUiECh5LBLPIxhYl/s1600/SFTPAdapterConfigurationForRename1.png" height="400" width="358" /></a></div>
<br />
<br />
One issue can occur
though if you use this technique to move files to a file archive in order to
have a log on the ftp server side of all files that has been processed. If the
filename is already available in the archive folder and the adapter tries to move
yet another file to this folder with the same name, it will fail. It will be
logged in the event log as "<i>Method: Blogical.Shared.Adapters.Sftp.SharpSsh.Sftp.Rename<br />Error: Unable to rename /home/marcus/btstest/testfile.xml to /home/marcus/btstest/archive/testfile.xml</i>", but the original file will be left in the pickup
folder on the SFTP site.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgn6varsVeZQ82JP08REY_rs9IeXPZFJGYaqh9Kw7-RuQliYtJ5N88ixFKkUZCATb2crOZQLrX59J4Nxa8qhDNKqEpmmNcPlCHhW7t0sb_Of6Hgz-KdbVTrMUbxUByGWGjJB2rcnnp3HV39/s1600/SFTPAdapterErrorWhenRenaming1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgn6varsVeZQ82JP08REY_rs9IeXPZFJGYaqh9Kw7-RuQliYtJ5N88ixFKkUZCATb2crOZQLrX59J4Nxa8qhDNKqEpmmNcPlCHhW7t0sb_Of6Hgz-KdbVTrMUbxUByGWGjJB2rcnnp3HV39/s1600/SFTPAdapterErrorWhenRenaming1.png" height="277" width="400" /></a></div>
<br />
BizTalk will not try to process this file again, until
you restart the host that is. Then it will be picked up once more, sent to the
messagebox and the rename function will fail again. You could make it a bit safer by using the<i> %DateTime%</i> or <i>%UniversalDateTime%</i> macros that also are available besides <i>%SourceFileName%</i>. Yet another option is to extend the BatchHandler.cs with the <i>%MessageID%</i> macro and create a GUID to add to the filename in order to get it truly unique.</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4985762676722907262.post-58960490970276130362014-03-31T11:34:00.003+02:002014-03-31T11:34:48.101+02:00Fix for jerky mouse movements in remote desktop/Citrix sessions to Windows Server 2012When connecting with Citrix to a Windows Server 2012, you might experience that the mouse pointer is lagging severely causing a jerky movement and making it a complete dud trying to make any proper work on the server.<br />
<br />
If this is the case, you should make sure that the Enable pointer shadow checkbox in the Mouse Properies is unchecked. This feature has been the issue with many machines I've encountered lately and unchecking the property has made the UI more enjoyable.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3L2TvHd6nXtpe8-W822k-d1aX3DOnh-uNP3jNU5YVXC6PfSqHvC3SP0XmJCCIGpxnlfI-udHZeXVtU6TFNJMv942VUra6cp4zIK-I2c54EU20-VfQ_yIvURXU7XVskc4fBRVCEm-RsrE1/s1600/MousePropertiesShadowWindowsServer2012.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3L2TvHd6nXtpe8-W822k-d1aX3DOnh-uNP3jNU5YVXC6PfSqHvC3SP0XmJCCIGpxnlfI-udHZeXVtU6TFNJMv942VUra6cp4zIK-I2c54EU20-VfQ_yIvURXU7XVskc4fBRVCEm-RsrE1/s1600/MousePropertiesShadowWindowsServer2012.png" /></a></div>
<br />Unknownnoreply@blogger.com7tag:blogger.com,1999:blog-4985762676722907262.post-51668805209407980222014-03-07T12:05:00.001+01:002014-03-07T12:05:31.771+01:00Recreating a BizTalk Active Directory group will cause access to BizTalk to failWhen setting up and configuring a BizTalk environment you will also add the necessary <a href="http://msdn.microsoft.com/en-us/library/aa577661.aspx" target="_blank">Active Directory groups</a> to allow access for different accounts to the platform.<br />
<br />
In most cases, you will not touch these groups again, but there might come a time when you remove and add the groups with the same name within Active Directory. Doing so will change the SID of the group and it will no longer match the SID stored in SQL Server for the Login.<br />
<br />
Trying to access the BizTalk Server Administration Console as a BizTalk Server Operator will for instance yield the following error when the corresponding AD group has been recreated:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOT-s0vHfzIDKHuran97U9iCOpRBS41meoEMTi3-Tg9bmZ8fUZv9ncTe41hsUf3j09KEBigfT5hCEoVJabOMJ2-plb0qh-v6o0jtXFBZhc3IRPck_Age6gWWSm8ezSY1P8IOItAntMYU7k/s1600/BizTalkServerAdministrationCannotAccessSQLServer_1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOT-s0vHfzIDKHuran97U9iCOpRBS41meoEMTi3-Tg9bmZ8fUZv9ncTe41hsUf3j09KEBigfT5hCEoVJabOMJ2-plb0qh-v6o0jtXFBZhc3IRPck_Age6gWWSm8ezSY1P8IOItAntMYU7k/s1600/BizTalkServerAdministrationCannotAccessSQLServer_1.png" /></a></div>
<br />
You will get an error saying "BizTalk Server cannot access SQL Server. [...] Access permissions have been denied to the current user. [...] Login failed for user [...]".<br />
<br />
You will also notice a logged error in SQL Server saying that "Login failed for user [...] Reason: Could not find a login matching the name [...]" <br />
<br />
When looking at both the Active Directory accounts/groups as well as the SQL Server security settings, everything will look ok.<br />
<br />
In order to correct this, you will have to remove and then add the corresponding Login in SQL Server. This might also cause you to have to delete and then add the corresponding User in the different BizTalk Databases (in general the BizTalkMgmtDb, BizTalkDTADb and BizTalkMsgBoxDb). This will also be notified by SQL Server when removing the Login.<br />
<br />
After doing these remove/adds in SQL Server, you should be able to access the resources as expected.<br />
<br />
Note that this is documented briefly in the <a href="http://msdn.microsoft.com/en-us/library/aa952926.aspx" target="_blank">Troubleshooting BizTalk Server Administration page on MSDN</a>, but you more or less have to know where/and for what to look in order to find it.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4985762676722907262.post-61681902051027639832014-02-28T18:02:00.000+01:002014-03-09T18:21:55.296+01:00The difference between single and double quotes in PowerShellI had a colleague ask me the other day about whether there was a difference between using single or double quotes when defining a string variable in PowerShell. For that specific questions, the answer was "no". However, there is an important distinction to make between the two.<br />
<br />
With double quotes, the text within the quotes will be parsed. For instance, the following code will output "Hello Marcus":<br />
<br />
<span style="font-family: "Courier New",Courier,monospace; font-size: small;">$name = 'Marcus'</span><br />
<span style="font-family: "Courier New",Courier,monospace; font-size: small;">$output = "Hello $name"</span><br />
<span style="font-family: "Courier New",Courier,monospace; font-size: small;">write-host $output</span><br />
<br />
However, when changing the second line to using single quotes as so:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace; font-size: small;">$output = 'Hello $name'</span><br />
<br />
The output will instead be "Hello $name"<br />
<br />
The parsers handling of the different quotes also means that if you are to use escape characters, for instance `n, you have to put the string within double quotes for the escape characters to work. If you want to use a double quote within such a string, you can write it using the escape character:<br />
<br />
<span style="font-family: "Courier New", Courier, monospace; font-size: small;">$mystring = "This is a variable called `"mystring`""</span><br />
<br />
Having the possibility of using the two different quotes can also allow for creating strings that contain one of the two quote characters, for instance when building query strings:<br />
<br />
<span style="font-family: "Courier New", Courier, monospace; font-size: small;">$name = 'Marcus'</span> <br />
<span style="font-family: "Courier New",Courier,monospace; font-size: small;">$query = "SELECT Id, City from Customers WHERE Name LIKE '%$name%'"</span><br />
<br />
Knowing this difference between single and double quotes is quite crucial for being able to build PowerShell scripts and not get into a mess when trying to create dynamic execution of other scripts or programs that require parameters to be passed to them.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4985762676722907262.post-24757302864079657032013-11-19T17:37:00.000+01:002013-11-20T09:17:56.687+01:00Base64 encode/decode part of messages in mapThis post is to show how to base64 encode or decode a part of a message (or the entire input message for that matter) and output the resulting string in an element in the output message.<br />
<br />
The technique used allows for execution of inline C# (or VB) code from another script functoid using inline XSLT / XSLT Template.<br />
<br />
The input and output schemas looks like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbpw0hLWlgUsLOMqowvpp9fQWiwW-bJF5_PykskZOV3n_sfuH0Kdir3abUYclGGmZ_L4QjXFGUQdyUoZy5nSZXbGwSPkSzGMuSQF8CeGaGKecrKfQhY1Av26QYpsQwh673wUBUPDwiLlbK/s1600/Base64EncodeInMap_Map2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbpw0hLWlgUsLOMqowvpp9fQWiwW-bJF5_PykskZOV3n_sfuH0Kdir3abUYclGGmZ_L4QjXFGUQdyUoZy5nSZXbGwSPkSzGMuSQF8CeGaGKecrKfQhY1Av26QYpsQwh673wUBUPDwiLlbK/s1600/Base64EncodeInMap_Map2.png" /></a></div>
<br />
<br />
<br />
In the example, our entire input message should be base64 encoded and the resulting string output to the EncodedData element in the output message. This element is of the type xs:string.<br />
<br />
First, we create a script functoid to hold our inline C# code for base64 encoding of the input node. When building such a method, one might first try to use string as the datatype for the input which will result in just the inner xml being transferred to the method. This is since the data from our XSLT call will be of the type MS.Internal.Xml.Cache.XPathDocumentNavigator. We therefore declare the input variable as <a href="http://msdn.microsoft.com/en-us/library/system.xml.xpath.xpathnavigator%28v=vs.110%29.aspx" target="_blank">XPathNavigator</a> instead to get access to the full XML node. The base64 encoding is done using the <a href="http://msdn.microsoft.com/en-us/library/system.text.encoding%28v=vs.110%29.aspx" target="_blank">System.Text.Encoding</a> class together with the <a href="http://msdn.microsoft.com/en-us/library/system.convert%28v=vs.110%29.aspx" target="_blank">System.Convert</a> class.<br />
<br />
<span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">public string Base64EncodeData(XPathNavigator param1)<br />{<br /> byte[] bytesToEncode =</span></span><br />
<span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span></span></span><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span></span></span>System.Text.Encoding.UTF8.GetBytes(param1.OuterXml);<br /> string encodedText = Convert.ToBase64String(bytesToEncode);<br /><br /> return encodedText;<br />}</span></span><br />
<br />
This functoid will not be connected to any node, but just left to "hang" in the map since we call it manually from another script functoid. Another solution to have it a bit cleaner would be to place this code in an external assembly and call that, but sometimes it is nice to have everything in the map.<br />
<br />
Next we create a script functoid and connect it to the destination element. We set the following Inline XSLT code:<br />
<br />
<span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"><xsl:variable name="data"></span></span><br />
<span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> <xsl:copy-of select="/" /></span></span><br />
<span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"></xsl:variable></span></span><br />
<span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"><br /></span></span>
<span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"><xsl:element name="EncodedData"></span></span><br />
<span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> <xsl:value-of select="userCSharp:Base64EncodeData($data)" /></span></span><br />
<span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"></xsl:element></span></span><br />
<br />
We first declare a variable that holds a copy of our source node which we simply specify using xpath.<br />
Then we call the previously configured method doing the encoding, and send the resulting data to our created destination element.<br />
<br />
The map will now look like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEia2VzxS3NsHuEc6CvW3CJYL61GrzI5D1JdNHil2dkHfId4BA03TMn37-qZTCZXNzOXM04Yt75jkidGOlhf7wyrP6UrEOzw5awXxfmk-9q8qkcIGjHKNSMSkejn32blktpqx3YHcx9OYhEC/s1600/Base64EncodeInMap_Map1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEia2VzxS3NsHuEc6CvW3CJYL61GrzI5D1JdNHil2dkHfId4BA03TMn37-qZTCZXNzOXM04Yt75jkidGOlhf7wyrP6UrEOzw5awXxfmk-9q8qkcIGjHKNSMSkejn32blktpqx3YHcx9OYhEC/s1600/Base64EncodeInMap_Map1.png" /></a></div>
<br />
<br />
The result from sending in a test XML is an XML with the entire original contents base64 encoded in an element.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs7FHolQ_swqchviBhNFv-M2wwkQN2Hr6CrzOX82sYJpwloiyGgdju_AK9z98vyAs13MnMkjugwJYdSJArDPDqsxdt_SVWi44WsWOQjPKTOo-lgA540QqrNMcexIUlFygUFFpDvjRCImo9/s1600/Base64EncodeInMap_Output1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs7FHolQ_swqchviBhNFv-M2wwkQN2Hr6CrzOX82sYJpwloiyGgdju_AK9z98vyAs13MnMkjugwJYdSJArDPDqsxdt_SVWi44WsWOQjPKTOo-lgA540QqrNMcexIUlFygUFFpDvjRCImo9/s1600/Base64EncodeInMap_Output1.png" /></a></div>
<br />Unknownnoreply@blogger.com4tag:blogger.com,1999:blog-4985762676722907262.post-56288652751404703792013-11-06T19:59:00.000+01:002013-11-10T17:52:49.232+01:00Pay attention when running Biztalk Server and SQL Server on servers in different timezonesThis post discusses what most likely is a seldom encountered setup, but nevertheless a possible one. Consider a global company that is using BizTalk. For various reasons, the SQL cluster will have Windows configured with another timezone than the rest of the servers.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhfBhr-gPtiWscZZgPlgWH-JSdjxHLnKgO1yl10uI_Iz5Sui6NXsNfMqzgH4qfRWginex9vhUqVkW372sHesxDy5ehOUP22b7YRp82WqHvCPx5EMxClI4slQEG6oAB9Picarkgo4wk3WNy/s1600/BizTalkAndSQLInDifferentTimezonesSetup1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhfBhr-gPtiWscZZgPlgWH-JSdjxHLnKgO1yl10uI_Iz5Sui6NXsNfMqzgH4qfRWginex9vhUqVkW372sHesxDy5ehOUP22b7YRp82WqHvCPx5EMxClI4slQEG6oAB9Picarkgo4wk3WNy/s1600/BizTalkAndSQLInDifferentTimezonesSetup1.png" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
This is our mock setup. BizTalk is located in the U.S. and at UTC-5 while the SQL server is in Sweden at UTC+1.<br />
<br />
During normal operations, this will work just fine. Each server will locally run in it's own timezone and all is good. The issues appear when working with service windows.<br />
<br />
Let's create a receive port with a corresponding receive location pulling in files from a folder.<br />
<br />
Now we want to use a service window on this receive location to only allow files to be processed during two hours every afternoon. This is in a real world scenario most likely going to be set up with a time reference to the BizTalk Server, i.e. the service window time will match the timezone on the BizTalk Server. In our example, it's 16:00 to 18:00 that is allowed, UTC+1.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsRyXHuQ4nwvrVmQe77l1eTUtzUGSMvfJ4eDWLW-7i_rIqj8tWAa11qNt9X305w7x332CXEIxJL6ZA3q0qqDXZb_Rf9VbGUH039i_zE8xaRXEe7aOGNZy4mN5kCkQF5WYUTHT6iUFy3Ahw/s1600/BizTalkAndSQLInDifferentTimezonesReceiveLocationServiceWindow1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="322" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsRyXHuQ4nwvrVmQe77l1eTUtzUGSMvfJ4eDWLW-7i_rIqj8tWAa11qNt9X305w7x332CXEIxJL6ZA3q0qqDXZb_Rf9VbGUH039i_zE8xaRXEe7aOGNZy4mN5kCkQF5WYUTHT6iUFy3Ahw/s400/BizTalkAndSQLInDifferentTimezonesReceiveLocationServiceWindow1.png" width="400" /></a></div>
<br />
<br />
If we look in the corresponding table in the SQL Server for this receive location, we can see that the time is set accordingly.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhr_EswPsIzdTyPLuRrUVp0nKw6_dxfsOfAys_sQlKlUezI0nDsAEu8dLikfUOWQpZwm8Gk7XKs0ccE8TqN2r6jnk3Hwql6JuXbwHEJKQUCutdMUlCONszlrJ263pVpXrNaHjO4Quv8Jvj/s1600/BizTalkAndSQLInDifferentTimezonesReceiveLocationServiceWindow2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="196" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhr_EswPsIzdTyPLuRrUVp0nKw6_dxfsOfAys_sQlKlUezI0nDsAEu8dLikfUOWQpZwm8Gk7XKs0ccE8TqN2r6jnk3Hwql6JuXbwHEJKQUCutdMUlCONszlrJ263pVpXrNaHjO4Quv8Jvj/s400/BizTalkAndSQLInDifferentTimezonesReceiveLocationServiceWindow2.png" width="400" /></a></div>
<br />
<br />
However, when the BizTalk Server rolls up to this time, the receive location will still not pull the file in! Why is that?<br />
<br />
Well, it seems that when BizTalk is checking if the receive location should be active or not, it compares the stored service window time with the local time on the SQL Server. BizTalk is after all heavily based on SQL Server. This have the effect that the time that we set on the BizTalk machine in UTC+1 and which is stored as such but without the timezone information will be used as is and hence be offset by six hours in this example.<br />
<br />
If we change the service window time in the BizTalk Administration Console to be offset with the corresponding six hours (i.e. 16:00 will be 10:00 instead), the receive location will trigger at the intended time.<br />
<br />
So far so good. If you know about this issue, it is easy to work around it. However, if you add in the normal complexity regarding daylight saving time that will change the offset yet a little twice a year, you are most likely heading towards a small headache!Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4985762676722907262.post-66842759232830329172013-10-30T17:24:00.000+01:002013-11-07T16:25:17.842+01:00Poor-man's scheduled trigger message task in BizTalkFrom time to time you might encounter the need for a trigger message in BizTalk. No matter the reason, you need a message that is sent to BizTalk every x minutes that in turn will trigger a process.<br />
<br />
In most cases, you will end up installing the <a href="http://biztalkscheduledtask.codeplex.com/">BizTalk Scheduled Task Adapter</a> from Codeplex. This adapter is throughly tested and well-used in different scenarious around the world and is a very valid option.<br />
<br />
If you do not want to install a third-party adapter for any reason but still need a trigger message to be sent every x minutes, you can script it using the Windows Task Scheduler. This solution will however require you to add the scheduled task to your monitoring solution to make sure that it stays active.<br />
<br />
Yet another solution that can be commonly seen is to have an SQL Agent job set a flag in a table every x minutes and then have BizTalk poll this table according to the usual techniques. <br />
<br />
My solution to creating a simple trigger message is to utilize the built-in features in BizTalk and not depend on any external trigger mechanism. By setting up a simple receive location with the WCF-SQL adapter, it can be made.<br />
<br />
First, create a receive port and location. In the WCF-SQL transport properties, set the endpoint URI to any valid SQL server. I use BizTalks management database in this case, since there won't be any load on it at all from this receive location and it always will be available.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpj6fBGwE-u9dUj-2Lul-MaSXKno5equeYwiLyf6wjYFTkWlYt5iOS9y_LJWBHihc1rz0lzkXhyi47xQiUs9Qe8TaQsStjb4epzeWjKgfFhCOKZMnxooDW6e_dYuTuClSrI2wjwHv__2jX/s1600/BizTalkWCFSQLTransportProperties1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpj6fBGwE-u9dUj-2Lul-MaSXKno5equeYwiLyf6wjYFTkWlYt5iOS9y_LJWBHihc1rz0lzkXhyi47xQiUs9Qe8TaQsStjb4epzeWjKgfFhCOKZMnxooDW6e_dYuTuClSrI2wjwHv__2jX/s400/BizTalkWCFSQLTransportProperties1.png" width="285" /></a></div>
<br />
Next, in the Binding section, set the XmlStoreProcedureRootNodeName to <i>TriggerRoot </i>and the XmlStoredProcedureRootNodeNamespace to <i>http://trigger/v1</i><br />
<br />
Using XmlPolling as InboundOperationType, you set the PolledDataAvailableStatement to <i>Select 1</i> to simply always trigger a polling statement execution. The PollingStatement in turn is set to<i> WITH XMLNAMESPACES(DEFAULT 'http://trigger/v1') select CURRENT_TIMESTAMP for xml raw ('Trigger'), ELEMENTS</i><br />
<br />
PollingIntervalInSeconds can be set to any interval you like. Also make sure that the PollWhileDataFound property is set to <i>False</i>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguWD6UeCrmJAv9Yokk6DeKw7GItXA4Vadqlm88pyXIo7etMV3ryivNgPCAom4w44ByCtI0YMKdY9NCgL-HDnmSJxXUt7UFLTXJSWl2KBhfAPdL8avtapl35ntvxIHuBnbkbqZUHIO4vl_T/s1600/BizTalkWCFSQLTransportProperties2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguWD6UeCrmJAv9Yokk6DeKw7GItXA4Vadqlm88pyXIo7etMV3ryivNgPCAom4w44ByCtI0YMKdY9NCgL-HDnmSJxXUt7UFLTXJSWl2KBhfAPdL8avtapl35ntvxIHuBnbkbqZUHIO4vl_T/s320/BizTalkWCFSQLTransportProperties2.png" width="241" /></a></div>
<br />
<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPHDCgu_C9nahzD6Wac6tChmXTSv4eOfBmAT4cwrf9w3ZG2OhomdqHFpIGirPf15WEIjmGYZRgNICpgnQaDTfXc3VS36o0oQwOuyAUtFFM1-1fbkCQMofy40gQc3qVAli4y8BEcOJpDum0/s1600/BizTalkWCFSQLTransportProperties3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPHDCgu_C9nahzD6Wac6tChmXTSv4eOfBmAT4cwrf9w3ZG2OhomdqHFpIGirPf15WEIjmGYZRgNICpgnQaDTfXc3VS36o0oQwOuyAUtFFM1-1fbkCQMofy40gQc3qVAli4y8BEcOJpDum0/s320/BizTalkWCFSQLTransportProperties3.png" width="241" /></a></div>
<br />
<br />
<br />
What this does is that when the receive location is started, the first statement will return 1, telling BizTalk that there is a message to be fetched and to execute the polling statement. This statement will return a raw xml message that will look like this:<br />
<br />
<TriggerRoot xmlns="http://trigger/v1"><br />
<Trigger>2013-09-14T12:20:11.037</Trigger><br />
</TriggerRoot><br />
<br />
You can then create a schema for this message and then in turn use it in your BizTalk solution to trigger a process on a timely schedule. Quick and simple and does the job. The bonus is that as long as the receive location is up and running, you know that it will create a message for you.<br />
<br />Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-4985762676722907262.post-39688933269866846882013-10-16T08:40:00.000+02:002013-10-16T08:40:45.624+02:00Captain Obvious to the rescue!<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1P6gok47slFh77pvJyURlDFk4-qJIr3M1CW-do-Y5nNAWUe0s_nnIxdRau8EsKsKSvIJyNhubpqGSZxthqPEVSh7TbZKs_F7hG771kOk6BQIXrZipRzrTddRftAMJx0p5FjmdqD9jC1UC/s1600/HttpError5032ServiceUnavailable.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="290" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1P6gok47slFh77pvJyURlDFk4-qJIr3M1CW-do-Y5nNAWUe0s_nnIxdRau8EsKsKSvIJyNhubpqGSZxthqPEVSh7TbZKs_F7hG771kOk6BQIXrZipRzrTddRftAMJx0p5FjmdqD9jC1UC/s400/HttpError5032ServiceUnavailable.png" width="400" /></a></div>
<br />
The serverRuntime@appConcurrentRequestLimit setting is being exceeded.<br />
<br />
Most likely causes: Setting is too low.<br />
Things you can try: Try increasing the value of the setting.<br />
<br />
Well, duh.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4985762676722907262.post-40312246393476898402013-08-20T19:03:00.000+02:002013-09-03T09:50:01.136+02:00Connecting BizTalk to Oracle RIB using JMS a.k.a netsh/netmon to the rescueI was tasked with setting up a connection between BizTalk and an <a href="http://www.oracle.com/us/products/applications/061928.html" target="_blank">Oracle RIB installation</a> using JMS. The JMS connection was handled using the <a href="http://www.jnbridge.com/JMS-BizTalk-Adapter.htm" target="_blank">JNBridge adapter</a>.<br />
<br />
Hooking up BizTalk to JMS doesn't pose too much of an issue thanks to good documentation from JNBridge. Most of the issues that occur is about getting proper access to the servers, having the correct parameters for the JMS topics, setting the Java parameters right and so on.<br />
<br />
As soon as those things got properly aligned, we successfully received messages published in the RIB to BizTalk. The next part was to send messages to the RIB.<br />
<br />
We could see messages leave BizTalk successfully, but nothing ever appeared in the JMS topic. No errors were logged anywhere on either side.<br />
<br />
After some error searching, I turned to do a trace using <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd569142%28v=vs.85%29.aspx">netsh.exe</a> and analyzing this in <a href="http://www.google.se/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&ved=0CC8QFjAA&url=http%3A%2F%2Fwww.microsoft.com%2Fen-us%2Fdownload%2Fdetails.aspx%3Fid%3D4865&ei=MxOjUYrOBdCQ4gT9-YDIDw&usg=AFQjCNGHpuNa95BwPYBZ6M8dDVIUBhIL3A&sig2=NgdLl9E97YvDzM6qZQXQSg" target="_blank">NetMon</a>. This showed that we had some handshaking going on coupled with the adapter running checks against the JMS setup to make sure that we could put a message on the topic. This resulted in an ORA-24033: no recipients for message error.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcW_3FEqp7BySMRAD9RddAiJfBIGhHOt961-LJDHdxPq0zpdQ9bw85gdselLX3qKriSZ3JlGi_bAQsMP7D4ror8dgPhmHrUnk1WfWTzUGpdwgNN-RpveCc7HCYqrjWaiNlcaMZXy06o23-/s1600/JMSAdapterNetMonTraceORA-24033.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="100" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcW_3FEqp7BySMRAD9RddAiJfBIGhHOt961-LJDHdxPq0zpdQ9bw85gdselLX3qKriSZ3JlGi_bAQsMP7D4ror8dgPhmHrUnk1WfWTzUGpdwgNN-RpveCc7HCYqrjWaiNlcaMZXy06o23-/s400/JMSAdapterNetMonTraceORA-24033.png" width="400" /></a></div>
Unfortunately, this error message is eaten up by the framework and not
forwarded to the adapter so that it can be logged properly. The only way
to see it is by running a trace on the traffic. <br />
<br />
The error message we got is <a href="http://docs.oracle.com/cd/E11882_01/server.112/e17766/e19999.htm" target="_blank">explained in the documentation</a> as:<br />
<blockquote class="tr_bq">
<dl>
<dt><span class="msg">ORA-24033: no recipients for message</span> </dt>
<dd><div class="msgexplan">
<span class="msgexplankw">Cause:</span> An
enqueue was performed on a queue that has been set up for multiple
dequeuers but there were neither explicit recipients specified in the
call nor were any queue subscribers determined to be recipients for this
message.</div>
</dd><dd><div class="msgaction">
<span class="msgactionkw">Action:</span> Either pass a list of recipients in the enqueue call or add subscribers to the queue for receiving this message.</div>
</dd></dl>
</blockquote>
<br />
I looked around for a solution to this error since we couldn't find any issues with the topic itself. There were a subscriber properly set up and no issues regarding access were to be found.<br />
<br />
In <a href="http://www.soabyte.com/2010/04/troubleshooting-and-workarounds.html" target="_blank">an older blog post</a> I could find something to point me in the right direction. In order to send messages to Oracle RIB, you have to set a threadValue parameter in the JMS header (which can be read about in the RIB documenation if you know where to look). This is in turn used in the subscription rule on the other end. If this parameter isn't set, there is no subscriber available since it is a mandatory field in the selector.<br />
<br />
After setting a threadValue element to "1" using a custom pipeline component, the messages was successfully sent to the RIB which both can be seen in the topic itself as in the trace where the update to the table is visible with the message as a parameter.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2WIori7rgL-F894P1lTAnEC4Ud8j13AKb1ZB70xHEVVdpboxrUGmeyBMRysIiczjBBhaf7_hATL8idCrRV8fn7loUEx61WnhuMWxNRuA2i0nYSuCLAqXCXEmgQMzW9PsNnqobBdyFZfXY/s1600/JMSAdapterNetMonTraceSuccessSend.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="286" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2WIori7rgL-F894P1lTAnEC4Ud8j13AKb1ZB70xHEVVdpboxrUGmeyBMRysIiczjBBhaf7_hATL8idCrRV8fn7loUEx61WnhuMWxNRuA2i0nYSuCLAqXCXEmgQMzW9PsNnqobBdyFZfXY/s400/JMSAdapterNetMonTraceSuccessSend.png" width="400" /></a></div>
<br />
NetMon or a similar tool is invaluable when tracking down similar issues. It is not the first time that NetMon (or WireShark) has provided information that is needed in order to get things to work.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4985762676722907262.post-40384754902419582792013-06-18T19:58:00.000+02:002013-08-19T11:42:43.379+02:00Leaving password blank in BizTalk 2013 SFTP adapter will cause host instance to run at 100% CPU without warningA very interesting tidbit appeared on a server running BizTalk 2013 and using the brand new SFTP adapter that is bundled with the product.<br />
<br />
As soon as a file was sent to an SFTP server, the host instance running the adapter would spin up to 100% CPU and stay there. The file would not be sent and no warnings or errors written to the event log.<br />
<br />
After being tasked with trying to find out the issue behind this, I started with the normal tasks coupled with a host spinning up without any reason: checking the tracking settings, looking at the messagebox regarding rouge messages, zombies etc. Nothing could be found.<br />
<br />
It wasn't until I tried to set up a copy of the flow on another 2013 server that I noticed that the password field in the Send Port properties was blank. Even with an entered password of "" the password field should display a bunch of stars to mask the password (or lack of one).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgM9tUuxoUTkFNqhp7IRrEPh7M5CprVfk-247ciDpta_hLkxQRLUZlgEmYuS85GIbwLWMcUYiAenFaUOQJBEcggJ79eTkHnMNAKjeGkZUIgwz2ILNGNXdI2afGGXu7z9NY83SMa4thy7tHT/s1600/SftpPasswordIsBlank1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgM9tUuxoUTkFNqhp7IRrEPh7M5CprVfk-247ciDpta_hLkxQRLUZlgEmYuS85GIbwLWMcUYiAenFaUOQJBEcggJ79eTkHnMNAKjeGkZUIgwz2ILNGNXdI2afGGXu7z9NY83SMa4thy7tHT/s400/SftpPasswordIsBlank1.png" width="343" /></a></div>
<br />
<br />
I set the password to the correct one, and started the host again. Now the file was sent and the host stayed at normal CPU load.<br />
<br />
When looking into this, I noticed that when exporting the binding for the send port when the password wasn't set, the CustomProps in the TransportTypeData element never included the Password element. When setting either a blank password or a proper one, the binding will include a password placeholder of <password vt="1"> which can be translated to NULL, i.e. there is no password defined (it is never written to the binding file for security reasons). But if you never set a password, this field is never written to the binding file at all!</password><br />
<br />
This is important to be aware of since I also noticed that if you try to set the password to "blank", by entering a character and then deleting it again and then saving, it is not entered since the GUI will interpret it as nothing has changed and therefore not set the password field to blank, leaving it completely undefined. Instead you have to enter a dummy character, save, enter the property dialog again and delete the character before doing the final save. That way the blank password will be properly saved.Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-4985762676722907262.post-84448760605615103282013-05-08T18:38:00.000+02:002013-10-25T23:46:35.571+02:00Remember to set the child delimeter even for single element lines in a flat file schema if using wrap charactersI briefly ran into this when creating a larger flat file schema for a message. The input message had line tags that I could use to identify the different rows. Most of the rows had several distinct fields to read, but there were rows with only the tag and a string of text encapsulated in quotation marks.<br />
<br />
As an example, we'll use an input file like so:<br />
<br />
<span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;">#FIRST 12345 "This is the first string"<br />#SECOND "This is the second string"</span></span><br />
<br />
This can then be used to create a schema which identifies the two distincs rows based on their tag (#FIRST and #SECOND respectively) and then split the fields on a delimiter of 0x20 (the space character).<br />
<br />
The schema can be like this:<br />
<br />
<span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> <?xml version="1.0" encoding="utf-16"?><br /><xs:schema xmlns="http://TestProject.Schemas" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" elementFormDefault="qualified" targetNamespace="http://TestProject.Schemas" xmlns:xs="http://www.w3.org/2001/XMLSchema"><br /> <xs:annotation><br /> <xs:appinfo><br /> <schemaEditorExtension:schemaInfo namespaceAlias="b" extensionClass="Microsoft.BizTalk.FlatFileExtension.FlatFileExtension" standardName="Flat File" xmlns:schemaEditorExtension="http://schemas.microsoft.com/BizTalk/2003/SchemaEditorExtensions" /><br /> <b:schemaInfo standard="Flat File" codepage="65001" default_pad_char=" " pad_char_type="char" count_positions_by_byte="false" parser_optimization="speed" lookahead_depth="3" suppress_empty_nodes="false" generate_empty_nodes="true" allow_early_termination="false" early_terminate_optional_fields="false" allow_message_breakup_of_infix_root="false" compile_parse_tables="false" root_reference="Root" /><br /> </xs:appinfo><br /> </xs:annotation><br /> <xs:element name="Root"><br /> <xs:annotation><br /> <xs:appinfo><br /> <b:recordInfo structure="delimited" child_delimiter_type="hex" child_delimiter="0xD 0xA" child_order="postfix" sequence_number="1" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" /><br /> </xs:appinfo><br /> </xs:annotation><br /> <xs:complexType><br /> <xs:sequence><br /> <xs:annotation><br /> <xs:appinfo><br /> <groupInfo sequence_number="0" xmlns="http://schemas.microsoft.com/BizTalk/2003" /><br /> </xs:appinfo><br /> </xs:annotation><br /> <xs:element name="First"><br /> <xs:annotation><br /> <xs:appinfo><br /> <b:recordInfo tag_name="#FIRST" structure="delimited" child_delimiter_type="hex" child_delimiter="0x20" child_order="prefix" sequence_number="1" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" /><br /> </xs:appinfo><br /> </xs:annotation><br /> <xs:complexType><br /> <xs:sequence><br /> <xs:annotation><br /> <xs:appinfo><br /> <groupInfo sequence_number="0" xmlns="http://schemas.microsoft.com/BizTalk/2003" /><br /> </xs:appinfo><br /> </xs:annotation><br /> <xs:element name="Id" type="xs:string"><br /> <xs:annotation><br /> <xs:appinfo><br /> <b:fieldInfo justification="left" sequence_number="1" /><br /> </xs:appinfo><br /> </xs:annotation><br /> </xs:element><br /> <xs:element name="Text" type="xs:string"><br /> <xs:annotation><br /> <xs:appinfo><br /> <b:fieldInfo justification="left" sequence_number="2" wrap_char_type="char" wrap_char="&quot;" /><br /> </xs:appinfo><br /> </xs:annotation><br /> </xs:element><br /> </xs:sequence><br /> </xs:complexType><br /> </xs:element><br /> <xs:element name="Second"><br /> <xs:annotation><br /> <xs:appinfo><br /> <b:recordInfo tag_name="#SECOND" structure="delimited" child_order="prefix" sequence_number="2" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" /><br /> </xs:appinfo><br /> </xs:annotation><br /> <xs:complexType><br /> <xs:sequence><br /> <xs:annotation><br /> <xs:appinfo><br /> <groupInfo sequence_number="0" xmlns="http://schemas.microsoft.com/BizTalk/2003" /><br /> </xs:appinfo><br /> </xs:annotation><br /> <xs:element name="Text" type="xs:string"><br /> <xs:annotation><br /> <xs:appinfo><br /> <b:fieldInfo justification="left" sequence_number="1" wrap_char_type="char" wrap_char="&quot;" /><br /> </xs:appinfo><br /> </xs:annotation><br /> </xs:element><br /> </xs:sequence><br /> </xs:complexType><br /> </xs:element><br /> </xs:sequence><br /> </xs:complexType><br /> </xs:element><br /></xs:schema></span></span><br />
<br />
This will however generate an output like so:<br />
<span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"><br /></span></span>
<span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"><Root xmlns="http://TestProject.Schemas"><br /> <First><br /> <Id>12345</Id><br /> <Text>This is the first string</Text><br /> </First><br /> <Second><br /> <Text>"This is the second string"</Text><br /> </Second><br /></Root></span></span><br />
<br />
Notice the quotation marks that are still left in the string even if we have defined them as a wrap character in the schema for that field.<br />
<br />
In order to make them disappear from the field properly in the same manner as in the first line of text, we have to set the Child Delimiter parameter on the "Second" child record:<br />
<br />
<span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> <xs:element name="Second"><br /> <xs:annotation><br /> <xs:appinfo><br /> <b:recordInfo tag_name="#SECOND" structure="delimited" child_order="prefix" sequence_number="2" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" child_delimiter_type="hex" child_delimiter="0x20" /> <br /> </xs:appinfo><br /> ...</span></span><br />
<br />
Which in turn will make the quotation marks disappear from our element data.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4985762676722907262.post-53141896017544234572013-03-23T15:51:00.000+01:002013-06-20T11:38:06.336+02:00MSDTC error after cloning a virtual machineA common development task is to clone virtual servers for different development scenarios. I myself have a bunch of virtual servers configured that I clone in order to get new fresh installs to lab with.
However, when cloning machines in a BizTalk setup, you have to be aware of the issues that can develop due to the need for unique identification keys in MSDTC.
When cloning a server to two instances and using one for SQL Server and the other as the BizTalk application server, MSDTC will not work. When running DTCTester the following error will appear:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg58IWxv4D2iXuMqS6nen6gBzzJCF4geLSHfRDdMdx9NRQ87sM6-umrVBQ32MQji06iBDs2cCpiydsggDYuQWXAKtWMpEqCNsnscGGdcueo6_yfWzlfPNvvViwWaW2phNgdtMgQDI2S_sSj/s1600/MSDTCTesterErrorWhenCloningMachine1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="220" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg58IWxv4D2iXuMqS6nen6gBzzJCF4geLSHfRDdMdx9NRQ87sM6-umrVBQ32MQji06iBDs2cCpiydsggDYuQWXAKtWMpEqCNsnscGGdcueo6_yfWzlfPNvvViwWaW2phNgdtMgQDI2S_sSj/s400/MSDTCTesterErrorWhenCloningMachine1.png" width="400" /></a></div>
<br />
<blockquote class="tr_bq">
Error: SQLSTATE=24000,Native error=0,msg=[Microsoft][ODBC SQL Server Driver]Invalid cursor state</blockquote>
The reason in this case is that the CID GUID is not unique on the servers.<br />
<br />
Run regedit and browse to HKEY_CLASSES_ROOT\CID\ and find the GUID where Description is set to MSDTC (it is one of the four). The GUID should be exactly the same on the other server.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5gJSNHfKgQr8mlIlXBMsXm7vguBfNm2yjJkh0jbOGnWVIMlD6PKK9h3hlS1_XkwmucFgVBtyihGD8iIvpzOd6hBPSWmg4cFuPCxOfwl6RBq79lOelKal-BYR-N9pfHiXwRTny4JDud-FQ/s1600/MSDTCErrorCIDGUID.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="155" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5gJSNHfKgQr8mlIlXBMsXm7vguBfNm2yjJkh0jbOGnWVIMlD6PKK9h3hlS1_XkwmucFgVBtyihGD8iIvpzOd6hBPSWmg4cFuPCxOfwl6RBq79lOelKal-BYR-N9pfHiXwRTny4JDud-FQ/s400/MSDTCErrorCIDGUID.png" width="400" /> </a> </div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
In order to fix this, you have to uninstall and then install MSDTC again (or you could go the wild path and just set another GUID). Uninstalling/installing MSDTC is done via the command prompt.<br />
<br />
Open a command prompt as administrator and run the command<br />
<blockquote class="tr_bq">
msdtc -uninstall </blockquote>
followed by<br />
<blockquote class="tr_bq">
msdtc -install</blockquote>
Verify that the DTC coordinator has started up and check the CID values in the registry. When running MSDTCTester again it should show a successful result:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2kKNXtkZIVclI9RMDgz5D7EJLiuORbWnYrNbACu8gMIp7qSL3mDsrKCi4pcWoHVn9OVN7VrHm75c1kC0ikC6gl8VgwbOtaH26F_3Fh6fBZZj7K_cna9sY1vIzcP83hSRiG4iugI-6P57U/s1600/MSDTCTesterSuccess1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="205" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2kKNXtkZIVclI9RMDgz5D7EJLiuORbWnYrNbACu8gMIp7qSL3mDsrKCi4pcWoHVn9OVN7VrHm75c1kC0ikC6gl8VgwbOtaH26F_3Fh6fBZZj7K_cna9sY1vIzcP83hSRiG4iugI-6P57U/s400/MSDTCTesterSuccess1.png" width="400" /></a></div>
<br />
This error will be caught by the <a href="http://blogs.technet.com/b/jpierauc/archive/2007/12/18/msgboxviewer.aspx" target="_blank">BizTalk MessageBox Viewer</a>. It will show an error of<br />
<blockquote class="tr_bq">
<cid> is duplicated on servers <server 1=""> and <server 2=""> - Check if < server1> and <server 2=""> are not cluster nodes as CID must be unique on non-clustered servers!</server></server></server></cid></blockquote>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4985762676722907262.post-5315660883451356512013-02-26T18:29:00.000+01:002013-02-27T11:15:12.336+01:00Script BizTalk Application export to .msi with options using PowerShellI've had the need to export BizTalk Applications using scripts, but with the requirement to not export web directories or global parties to the .msi file.<br />
<br />
This can be done using the GUI:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXln5Kdmujsfo1Q3gqTBDL-2l4u5IFA10DDB7FTTLznpuLWA0X_bhw1T3LebgjWzxXOitpTxYK__mJa1eldUfTBBgORQk1OC0bXNM4tIiQjNtEFVbi64yHMMMZ1sPKE_-aEYSG0cVkBcED/s1600/ExportMsiWithoutWebDirAndGlobalPartiesGui1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="328" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXln5Kdmujsfo1Q3gqTBDL-2l4u5IFA10DDB7FTTLznpuLWA0X_bhw1T3LebgjWzxXOitpTxYK__mJa1eldUfTBBgORQk1OC0bXNM4tIiQjNtEFVbi64yHMMMZ1sPKE_-aEYSG0cVkBcED/s400/ExportMsiWithoutWebDirAndGlobalPartiesGui1.png" width="400" /></a></div>
<br />
However, it cannot be done (that I know of) using the <a href="http://msdn.microsoft.com/en-us/library/aa560469.aspx" target="_blank">btstask command with the exportapp parameter</a>.<br />
<br />
I opted for creating a PowerShell script that more or less extends the btstask exportapp command<span style="font-size: small;"><span style="font-family: inherit;">. The script takes a few parameters making it a bit <span style="font-size: small;">more versatile</span>:</span></span><br />
<br />
<i>$appName</i> is the name of the BizTalk application to export<br />
<i>$exportPath</i> is the path to write the .msi file to<br />
<i>$exportWebDir</i> is a boolean indicating whether to also export web directories or not<br />
<i>$removeDefaultBinding</i> is a boolean controlling whether the default bindings will be written to the .msi file or not. This is handy to remove in those cases you want to just keep bindings for dev/test/production environments.<br />
<i>$exportGlobalParties</i> is a boolean controlling whether to include the Global Parties in the binding file or not. These will of course not be written if for instance you only have the default bindings and set the parameter $removeDefaultBinding to false and $exportGlobalParties to true, since the binding file never will be written at all.<br />
<br />
The script basically dumps a ResourceSpecification file which then gets modified depending on the parameters entered. This ResourceSpecification is then used as input to the btstask exportapp command creating an .msi file according to our needs.<br />
<br />
The full script looks like this:<br />
<br />
<span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;">param($appName, $exportPath, $exportWebDir, $removeDefaultBinding, $exportGlobalParties)<br /><br />Write-Output "Exporting ResourceSpec..."<br />BTSTask ListApp <span style="font-size: x-small;">/</span>ApplicationName:$appName <span style="font-size: x-small;">/</span>ResourceSpec:$pwd\ResourceSpecTemp.xml<br /><br />If (!($?))<br />{<br /> throw "Could not export resource specification. Verify application name."<br />}<br /><br />Write-Output "Reading ResourceSpec..."<br />$xmlResource = [xml] (Get-Content $pwd\ResourceSpecTemp.xml)<br /><br />If ($exportWebDir -eq $false)<br />{<br /> Write-Output "Removing web directories..."<br /> $delnodes = $xmlResource.SelectNodes("/*[local-name()='ResourceSpec' and namespace-uri()='http://schemas.microsoft.com/BizTalk/ApplicationDeployment/ResourceSpec/2004/12']/*[local-name()='Resources' and namespace-uri()='http://schemas.microsoft.com/BizTalk/ApplicationDeployment/ResourceSpec/2004/12']/*[local-name()='Resource' and namespace-uri()='http://schemas.microsoft.com/BizTalk/ApplicationDeployment/ResourceSpec/2004/12'][@Type='System.BizTalk:WebDirectory']")<br /><br /> ForEach($delnode in $delnodes)<br /> {<br /> [void]$xmlResource.ResourceSpec.Resources.RemoveChild($delnode)<br /> }<br />}<br /><br />If ($removeDefaultBinding -eq $true)<br />{<br /> Write-Output "Removing Default binding info..."<br /> $delnodes = $xmlResource.SelectNodes("/*[local-name()='ResourceSpec' and namespace-uri()='http://schemas.microsoft.com/BizTalk/ApplicationDeployment/ResourceSpec/2004/12']/*[local-name()='Resources' and namespace-uri()='http://schemas.microsoft.com/BizTalk/ApplicationDeployment/ResourceSpec/2004/12']/*[local-name()='Resource' and namespace-uri()='http://schemas.microsoft.com/BizTalk/ApplicationDeployment/ResourceSpec/2004/12'][@Type='System.BizTalk:BizTalkBinding'][@Luid='Application/$appName']")<br /><br /> ForEach($delnode in $delnodes)<br /> {<br /> [void]$xmlResource.ResourceSpec.Resources.RemoveChild($delnode)<br /> }<br />}<br /><br />Write-Output "Saving modified ResourceSpec..."<br />$xmlResource.Save("$pwd\ResourceSpecTemp.xml")<br /><br />Write-Output "Exporting application $appName..."<br /><br />If ($exportGlobalParties -eq $true)<br />{<br /> $globalPartiesParam = "/G"<br />}<br />else<br />{<br /> $globalPartiesParam = ""<br />}<br /><br />BTSTask ExportApp /ApplicationName:$appName /Package:$exportPath\$appName.msi /ResourceSpec:$pwd\ResourceSpecTemp.xml $globalPartiesParam<br /><br />If (!($?))<br />{<br /> throw "Could not export application. Verify application name and parameters."<br />}<br /> <br />Write-Output "Cleaning up..."<br />Remove-Item $pwd\ResourceSpecTemp.xml<br /><br />Write-Output "DONE!"<br /><br />Exit 0</span></span><br />
<br />
<span style="font-size: small;"><span style="font-family: inherit;">And will be call<span style="font-size: small;">ed like so:</span></span></span><br />
<br />
<span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;">ExportBtsMsi.ps1 BtsDemo1 "C:\"<span style="font-size: x-small;"> false false false</span></span><br />
<br />
<span style="font-size: small;"><span style="font-family: inherit;">W<span style="font-size: small;">hich will result in out<span style="font-size: small;">put like this<span style="font-size: small;">:</span></span></span></span></span></span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgav9KVyUNOgKu93cnBWC1pSQNEmbvRTvnTJpvl-Bng9qBFJZhN6yLHee7sBLjCGP8ZwznttsN76WCj2EuAfDUwawbQzjm0zR6-jLSfQqZtutLg5jnk9SFVsBaticgu3PSOvW3ZQcJVY3Mz/s1600/ExportBtsMsiUsingPowerShell1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="255" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgav9KVyUNOgKu93cnBWC1pSQNEmbvRTvnTJpvl-Bng9qBFJZhN6yLHee7sBLjCGP8ZwznttsN76WCj2EuAfDUwawbQzjm0zR6-jLSfQqZtutLg5jnk9SFVsBaticgu3PSOvW3ZQcJVY3Mz/s400/ExportBtsMsiUsingPowerShell1.png" width="400" /></a></div>
<br />Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-4985762676722907262.post-23015492927161984582013-01-18T16:05:00.000+01:002013-01-22T13:11:49.699+01:00Run Microsoft pre-configured VHD evaluations without Hyper-V using VirtualBoxI needed to run the <a href="http://www.microsoft.com/en-us/download/details.aspx?id=13624" target="_blank">BizTalk 2010 VHD</a> for demo purposes, but lacked access to a Windows 2008 Server with Hyper-V in order to run the virtual machine.<br />
<br />
My first attempt was to simply mount the VHD file in a newly configured Virtual PC machine. This failed with the virtual machine rebooting shortly after start.<br />
<br />
Next I tried to create a new virtual machine in <a href="https://www.virtualbox.org/" target="_blank">VirtualBox</a>, giving me pretty much the same result, but with a bluescreen flashing past just before reboot.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAuFYUsMxpKXW9sw67k556aRK91FRsJW5nvFjDwNqUIEUdpcSjKCz7-M6oUTaUCY_7nzKMYLryCIVyC2IWZNi9KYhcIsctE9jxc7TlVhZfSe5XdPvPeglL3eGoeVnQwahBJJGissbjpnT4/s1600/BTS2010VboxCreateVM1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="355" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAuFYUsMxpKXW9sw67k556aRK91FRsJW5nvFjDwNqUIEUdpcSjKCz7-M6oUTaUCY_7nzKMYLryCIVyC2IWZNi9KYhcIsctE9jxc7TlVhZfSe5XdPvPeglL3eGoeVnQwahBJJGissbjpnT4/s400/BTS2010VboxCreateVM1.png" width="400" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8e7UaQppTzva5MkEPqGEgpURMDDTUoreuJmOA3O6chmQVbQCqc7ft94eHEmzvsk1OlEaee3pDY6-Ze2SSXHM3F72VFHbAJ-0CwmGkR66AhexZkecCbW3iits2SuHJf21IVW-AdjhVCUo0/s1600/BTS2010VboxUseExistingDrive1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="381" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8e7UaQppTzva5MkEPqGEgpURMDDTUoreuJmOA3O6chmQVbQCqc7ft94eHEmzvsk1OlEaee3pDY6-Ze2SSXHM3F72VFHbAJ-0CwmGkR66AhexZkecCbW3iits2SuHJf21IVW-AdjhVCUo0/s400/BTS2010VboxUseExistingDrive1.png" width="400" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiz95BqYSoGeeJFzGWlQyPYVwZDhv2704jYRHLcHWpwWVcMO4ZRnf1LIi4nQrA53nCPZc1j0PCVKiY3agbwPNuU3Cd7BbIPsmo3bn7fJaEOIRgjLOfdkOidpN4F68ODfpbpOG-0PAXCeFJE/s1600/BTS2010VboxVMBlueScreen1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="341" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiz95BqYSoGeeJFzGWlQyPYVwZDhv2704jYRHLcHWpwWVcMO4ZRnf1LIi4nQrA53nCPZc1j0PCVKiY3agbwPNuU3Cd7BbIPsmo3bn7fJaEOIRgjLOfdkOidpN4F68ODfpbpOG-0PAXCeFJE/s400/BTS2010VboxVMBlueScreen1.png" width="400" /></a></div>
<br />
In the bluescreen that quickly flashes by, it is possible to see the error code 0x0000007B, also known as INACCESSIBLE_BOOT_DEVICE. This is an indication of a possible issue with the boot sector, device driver and similar things. It led me to take a peek at the storage settings for the virtual machine that showed me that the IDE controller had no disks attached (but a CD/DVD drive) and my added VHD file was attached to a SATA controller.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDBLmO8TODetcqm-G5vuGgfpiWKdNPS7LyyolqOVxStTs6lf7MH9wetBsiYRmhRXBVRslHNpOpbaoiPxCFNoqf1NdFLy9szLxeYmYQMUZILmOGR7SxKcrIn2EEayZF0bJK_2VlyeRfkJKF/s1600/BTS2010VboxVMStorageSettings1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="298" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDBLmO8TODetcqm-G5vuGgfpiWKdNPS7LyyolqOVxStTs6lf7MH9wetBsiYRmhRXBVRslHNpOpbaoiPxCFNoqf1NdFLy9szLxeYmYQMUZILmOGR7SxKcrIn2EEayZF0bJK_2VlyeRfkJKF/s400/BTS2010VboxVMStorageSettings1.png" width="400" /></a></div>
<br />
I removed the VHD file from the SATA controller and removed the controller completely. I then added a new harddisk to the IDE controller and assigned the VHD file to it, thinking that this most likely was how the VHD file was set up initially.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgA0TK3enClkX2rBYKHXNVIW5FaALPbH9A2jc3pR1JT4IpLW29a9sjdAorWyrJuUilecuphQ_cW0dzGlErRatpqoMzJGwfHKBiedLudKdbTVZtQgY1z0m-uXLJxmgANTIjVwFB_iUJxYHpC/s1600/BTS2010VboxVMStorageSettings2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="298" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgA0TK3enClkX2rBYKHXNVIW5FaALPbH9A2jc3pR1JT4IpLW29a9sjdAorWyrJuUilecuphQ_cW0dzGlErRatpqoMzJGwfHKBiedLudKdbTVZtQgY1z0m-uXLJxmgANTIjVwFB_iUJxYHpC/s400/BTS2010VboxVMStorageSettings2.png" width="400" /></a></div>
<br />
And indeed it was so. This made the virtual machine start up ok!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4zgH0xBRojK6HmHoQg7AsLlDvYsNpFs-adsoiGXMFUwiZQ8VeZPfcKYQalzsFMHoYWFjKCuOimEk9fFXmEll2CrJhcAHyEWrSxVmeCduWpkqK0GHWm4wZnU0fl8iLpo_yaUWUPuiQQj8U/s1600/BTS2010VboxVMRunning1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="325" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4zgH0xBRojK6HmHoQg7AsLlDvYsNpFs-adsoiGXMFUwiZQ8VeZPfcKYQalzsFMHoYWFjKCuOimEk9fFXmEll2CrJhcAHyEWrSxVmeCduWpkqK0GHWm4wZnU0fl8iLpo_yaUWUPuiQQj8U/s400/BTS2010VboxVMRunning1.png" width="400" /></a></div>
<br />
I did run into issues when logging on though since the admin password includes the character "@" which I was unable to type due to some issue with VirtualBox and the Alt Gr key on my keyboard that was needed to type the character in. This was however quickly remedied by using the ALT-sequence instead, typing ALT+064 for the "@" character.<br />
<br />
After a day of testing, I cannot see any issues in the VM, but everything is running just fine! For those that are using VMWare instead, the same solution should work just as well.Unknownnoreply@blogger.com5