0 Comments

I have written powershell scripts in Azure runbooks in Azure Automation. It’s not a new concept. It’s even from back in 2014

https://azure.microsoft.com/en-us/blog/azure-automation-your-sql-agent-in-the-cloud/

I started to use it because there is no SQL Agent in Azure SQL databases. I relied on SQL Agent to perform Ola’s database maintenance scripts. I use the Azure automation with Runbooks now for a long time to build reports from Azure SQL and have them send to people by SMTP.

The problem is that I string concatenate HTML in the powershell script and just put the results in an HTML enabled Email message. It is still a good option… Until a coworker requests an Excel attached to the mail…

Excel in Azure Runbook (Powershell)

I did build the powershell locally first.

image

When using the Azure Automation ISE add-on for Windows PowerShell ISE it hit me. The cloud probably has no Excel com/interop…

So I found this module to work with Excel in Powershell without Excel on GitHub. It uses Epplus. Which I mentioned in my post from 6 years ago.

But I realised that I could also just use Azure Functions and code in C# and have a time trigger. This enables me to write my beloved C# rather then scripting Powershell. I can also just use the Epplus nuget package.

The Azure functions v2 are now in preview and have .Net Standard support (which is great!)

The Visual Studio dialog can be unclear if you visit it for the first time and have no clue that the schedule uses CRON notation. Maybe they will change it, but now you know.


Good luck!

Pin on pinterest Plus on Googleplus Post on LinkedIn
0 Comments

I followed the guide but did not got it to work.

It just failed at step 3 and there was no error at all. I thought it had to do with me changing the project from .net Core 1.x to 2.0

image

But it was partially related to the dropdown below it.

The startup object was not set.

I had to set it to “Neo.Compiler.Program”

But after that, the publish did not work because “neon.dll” was missing in some folder.

This GitHub comment pointed me in the right direction:

https://github.com/neo-project/docs/issues/368#issuecomment-362181887

you should copy “neon.dll” manually in that dir. it’s just one dir below.

after that, the publish succeeded and the neon.exe reference was already in the path variable, so the Visual Studio and manually commandline option both worked!

image

https://github.com/neo-project/neo-compiler/issues/90

Good luck building for the Neo blockchain!

NEO (NEO) cryptocurrency

Pin on pinterest Plus on Googleplus Post on LinkedIn
0 Comments

Perhaps it’s because I was still in holiday-mode, but I kept getting a 403 error. Even when I added a `helloworld.html` in the `.well-known` dir. Which was driving me crazy. I even thought it was .net Core 2.x related because all full framework sites were renewing just fine, both MVC and Webform applications.

The answer for my situation was in this comment:

Do you have both http/https binding? http binding is required for it to work.

I did, but I remembered something about forcing to SSL for this website.

I searched my code, but all I could find was commented out:

image

image

So how did I manage to force visitors to the SSL version? I could not remember it. There was also no URL rewriting in the web.config. It was a checkbox in IIS which I forgot that I ever changed that setting! (sorry for the Dutch screenshot of IIS 8.5)

 image

It would be nice if the new version of Let’s Encrypt Win Simple would temporary disable it and afterwards restored it.

Here is the link to the latest version 1.9.6.2


Good luck and best wishes for 2018!

Pin on pinterest Plus on Googleplus Post on LinkedIn
0 Comments

We have a lot of customer data in our system and I wanted to have a shared contact list with all the customer data for my co-workers.

I looking into some Office365 docs and found this walkthrough to create the folder: https://www.cogmotive.com/blog/office-365-tips/create-a-company-shared-contacts-folder-in-office-365

snip_20160322100016

So afterwards you have an empty but shared contact folder. I thought that I needed the Microsoft Graph to access these contacts. Which would require my app to be in azure and it cannot have a command line only because of the authentication. More about that approach can be found here http://dev.office.com/getting-started/office365apis

But it seems that this is not needed for my simple one time import https://msdn.microsoft.com/en-us/office/office365/api/contacts-rest-operations

I thought that it might be a job for a PowerShell script and found this http://www.infinitconsulting.com/2015/01/bulk-import-contacts-to-office-365/

But there is an other option. Use Interop, because I as an Office365 user have Outlook 2016 on my Windows 10 machine and Visual Studio 2015. So create a new (console) application and add a reference to Outlook Interop:

I used this code to get to the “customers” address book:

using System;
using Outlook = Microsoft.Office.Interop.Outlook;

namespace UploadContactsToOffice365
{
    class Program
    {
        static void Main(string[] args)
        {
            var ap = new Outlook.Application();
            
            foreach(Outlook.Folder f in ap.Session.Folders)
            {
                if (f.Name.ToLower().Contains("openbare")) // jp openbare mappen (public folders)
                {
                    Console.WriteLine(f.FullFolderPath);
                    foreach (Outlook.Folder f2 in f.Folders)
                    {
                        if (f2.Name.ToLower().Contains("alle")) // alle openbare mappen (all public folders)
                        {
                            Console.WriteLine(f2.FullFolderPath);
                            foreach (Outlook.Folder f3 in f2.Folders)
                            {
                                if (f3.Name.ToLower().Contains("klanten")) // customers (folder name)
                                {
                                    Console.WriteLine(f3.FullFolderPath);
                                    foreach (Outlook.Folder f4 in f3.Folders)
                                    {
                                        if (f4.AddressBookName.ToLower().Contains("customers"))
                                        {
                                            Console.WriteLine(f4.FullFolderPath);
                                            Console.WriteLine("----------");

                                            /// display current items:
                                            //Outlook.Items oItems = f4.Items;
                                            //for (int i = 1; i <= oItems.Count; i++)
                                            //{
                                            //    Outlook._ContactItem oContact = (Outlook._ContactItem)oItems[i];
                                            //    Console.WriteLine(oContact.FullName);
                                            //    oContact = null;
                                            //}
                                            
                                            // add test item:

                                            Outlook.ContactItem newContact = (Outlook.ContactItem)ap.CreateItem(Outlook.OlItemType.olContactItem);
                                            try
                                            {
                                                newContact.FirstName = "Jo";
                                                newContact.LastName = "Berry";
                                                newContact.Email1Address = "somebody@example.com";
                                                newContact.CustomerID = "123456";
                                                newContact.PrimaryTelephoneNumber = "(425)555-0111";
                                                newContact.MailingAddressStreet = "123 Main St.";
                                                newContact.MailingAddressCity = "Redmond";
                                                newContact.MailingAddressState = "WA";
                                                newContact.Move(f4);
                                                newContact.Save();                                                
                                            }
                                            catch (Exception ex)
                                            {
                                                Console.WriteLine("The new contact was not saved. " + ex.Message);
                                            }
                                            
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            Console.ReadKey();
        }
    }
}

This is not the prettiest code I have written. So there must be a better way. But this is just a one time application to loop through some database records and add contacts. So I will just leave it like this. Please let me know in the comments if you have suggestions to improve readability. The code snippet will give this contact in your (and the rest of the companies) outlook:

If you are looking how to import a folder full with vcf cards you should take a look at this MSDN article.

This should give you enough pointers to bulk add contacts to a shared folder in Office365 (Outlook 2016)

Good luck!

Pin on pinterest Plus on Googleplus Post on LinkedIn
0 Comments

Lazy productive I as a developer am, I did not want to write a stored procedure. So I ended up with a lot of SQL statements which needed to be combined and executed only if the previous one succeeds.

However there was a timeout during the execution. It was strange because when I copy pasted the SQL statement in SMSS it worked perfectly and fast too. My mistake was to use a new SqlCommand object which was not part of the transaction. I needed to re-use the same sqlcommand. Here is some working code:

using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["myConString"].ToString()))
{
    con.Open();

    SqlCommand cmd = con.CreateCommand();
    SqlTransaction transaction = con.BeginTransaction();

    cmd.Connection = con;
    cmd.Transaction = transaction;

    try{
    
        cmd.CommandText = "SELECT productcode FROM products WHERE productid = " + productid;
        string code = cmd.ExecuteScalar().ToString();
    
        cmd.CommandText = "SELECT ProductID, ProductWeight, ProductEuroPrice, OrderID FROM ORDERPICKINGPRODUCTS WHERE orderid = " + orderid + " AND productid = " + productid;
        SqlDataReader sdr = cmd.ExecuteReader();
        DataTable dt = new DataTable();
        dt.Load(sdr);
    
        cmd.CommandText = "DELETE FROM ORDERPICKINGPRODUCTS WHERE orderid = " + orderid + " AND productid = " + productid;
        cmd.ExecuteNonQuery();
        transaction.Commit();
    }
    catch(Exception e)
    {
        transaction.Rollback();
    }
}
I know that it is better to use parameters https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.parameters%28v=vs.110%29.aspx

And the AddWithValue method… But this is just pseudo code and not in production. So don’t worry!

This is just a small sample to help people with a strange timeout which you can encounter if you use an sqlcommand outside the transaction.

 

Good luck!

Pin on pinterest Plus on Googleplus Post on LinkedIn