Settings to control sharing at the organization level in SharePoint and OneDrive Office 365

Collaborating with partners and clients external to your organization is bread and butter of many businesses. With our continued investments in external collaboration, SharePoint, OneDrive, and Teams is the hub for your external collaboration teamwork. Check the links above for details.

Happy Sharepoint-ing

1 domain with coexist between Office 365 and Gsuite

Can we do 1 (one) domain, and then we are split all the users with some users at Office 365 and some users again at Gsuite ? The answer is yes you can.

This scenario actually on our clients currently not a common, but we can help you.

Because maybe in some organizations want to coexist due to different reasons. The major reason is that user demands more and organizations want to cater to this ever demanding user base. Some users might be familiar with Office 365 while some might be familiar with Google Apps. Also, the organization might want to move their future email workloads from a different platform like Google Apps to Office 365 while still keeping their existing email domain intact.

In this article, my scenario is that I have 1 domain abc-abc.site then I have registered the domain to CloudFlare to manage my dns. Because cloudfare is free for one site and also easy to manage for sub domains.

Here is the demo that we will cover for this demo.

Here as below the steps that i did in on my testing :

  1. Create subsciption to GSuite and validate the domain above to able send an email.

To validate it, we will update some MX record on our DNS, here as below my sample for my domain

Then after the validation done, you can test sending an email. In here i am also create 2 users Agusto@xxx.xxx and Erna@xxx.xxx

2. Create subsciption to Office 365 and validate the same domain like we did in on Gsuite

Here as below the MX that we need to insert on our DNS :

Then after the validation done, Ini here i am also create 2 users aaron@xxx.xxx and kayla@xxx.xxx

3. Once that’s done, navigate to “Exchange Admin Center” by navigating to “Admin > Exchange”. This will open up a new tab. Once in the “Exchange Admin Center” under “Mail Flow” select “Accepted Domains”

Once done, it will open up the “Accepted Domain”

In the above figure, the domain that you own and the service domain Microsoft Provides are both visible. Make sure the domain that is used in the production is set to the default domain in the Office 365 portal. Currently, the domain type is set to “Authoritative”. This must be changed to “Internal Relay” as mail will be relayed to the Gmail Mail users from Office 365 mail users.

To set the domain type to an internal relay, simply double-click the “xxx.xxx” (The production domain) domain to bring up the settings box to change the domain type to a relay as shown below

4. Now all already set up, now we need to set up the Connector.

To create the Outbound email connector, within the “Mail Flow” section select “Connectors” and click “+” sign to create a new connector as shown 

In the next section, specify when to use the connector which is created. In this scenario, this connector is needed to relay emails only when emails are sent to someone@techiewithablog.com SMTP domain (In this scenario. In your scenario the domain name will be different). Therefore, under “When do you want to use this connector?”” select, “Only when email messages are sent to these domains” and click “+” to add the respective domain that is used in the respective scenario. In this case, the domain “techiewithablog.com” is added as shown in the below . Once done click “Next”.

In the next section, a smart host needs to be provided to configure Office 365 to route the relayed emails. This is going to be the Google smart host that should be specified. Therefore, include “aspmx.l.google.com” as the Google smart host as shown below and click “Save” and “Next”.

Since the MX records are currently pointed to Google, doing an NS lookup to the SMTP domain will get you the Smart Host.

Once in the next section, for “How should the Office 365 connect to your email server?” section, deselect “Always use transport layer security option” and click Next as below

This will now run a series of validation checks against the connector by sending an email to verify the connector is working properly. If everything goes smooth, the validations progressing should be successful and the final result as shown below. Once the validation is done, click “Close” 

If the validation is successful, the validation results will be shown as successful as shown in the below. Once done, click “Save” so that the connector is now ready to relay emails to Office 365 and Google Apps.

5. Done

This should now enable email co-existence between the two platforms.

If you need more futher to know about this feature, or need a help to migrate or setup like this scenario. We are Infinys team able help you. Please go to this site https://infinyscloud.com/en/help and we will soon to contact you.

Reference Article(s) : https://social.technet.microsoft.com/wiki/contents/articles/36118.configure-email-coexistence-between-office-365-google-apps.aspx


https://mymicrosoftexchange.wordpress.com/2015/06/21/how-to-configure-mail-flow-coexistence-between-gapps-and-o365-using-internal-relay-domains-and-mail-users

Migrate from Outlook to G Suite using free tool GSMMO from Google

On the few this month we have some project to do around email migration. There are migration to Microsoft Office 365, and also migration to Gsuite. Our company at Infinys System Indonesia also as patner for Microsoft Office 365, and Google Gsuite, we also can help the client to do assestment and also migration your existing email to Microsoft Office 365 or Google Gsuite.

On this article, i want to share about one of the tool that we are using currently from import a backup email as pst files then using GSMMO (G Suite Migration for Microsoft Outloook) we are importing to selected user on Gsuite email.

To download the tool GSMMO you can download it in here https://tools.google.com/dlpage/gsmmo/ and the choose version 32 / 64 bit under DOWNLOAD .MSI FILE (RECOMMENDED FOR ADMINS).

Here are the step as below :

  1. Export email into as pst file
  2. Download the Gsmmo, then install on your machine.
  3. Once the instalation done, run the tools and then application will come up the sign in page. Enter the username Gsuite then click continue

4. Then will go to Sign tool confirmation like the picture as below, then click button Next

5. Once the sign in confirmation done, then we can choose the pst file that we already prepared. On this dialog, we choose From PST File(s) then browse the PST on your machine, the you can choose option Migrate all data or Migrate only new data. Then you can click button Next to continue

6. After you click Next, now we have to choose which data that we want to import it. There many option on screen as below, like import Calendar, Contact, Email Messages. Once you already picked, click button Migrate

7. Once we already click button Migrate, then migration will start base on the selection data that we are want to migrate.

8. Migration completed.

After the migration completed, you can check the log on the Migration log file, and if need to migrate again you can click button Start New Migration.

9. Now we can check on the Gsuite email, and see all the result from import that we already done it.

Install EspoCRM using aaPanel control panel on Ubuntu 18.04

EspoCRM is a web application that allows users to see, enter and evaluate all your company relationships regardless of the type. People, companies, projects or opportunities — all in an easy and intuitive interface.

The reason i choose this software because saw on their documentation the application look simple and very intutieve and also for the installation step it is very easy.

Currently my virtual server that i hosted on Infinys Cloud  has installed software aaPanel as my control panel and as well  easy to me to manage my virtual server and also the application is free. Since the Cpanel no longer free,  this is one you can try it.

Here are the screenshot installation as below :

  1.  When all the installation already set up, like PHP,  web server /Nginx, Mysql and so on. I try this on port 1000, since the default port already used with other application

So first installation you can open your browser and type like sample this http://xxx-domain-name:xx-Port/install.php. Once you open, the first page it will like this below and choose your languange needed and Click Start to proceed to next step

espocrm1

 

2.  Checked the “I accept the Agreement” and the Click Next

espocrm2

 

3. Then you will face it with this screen, and put all the information about the database. Make sure you already create the database first, and the click Next to Proceed.

espocrm3

 

4. This is information for login as Administrator for this Application

espocrm5

 

5. Setting the System settings

espocrm6

 

6. Settting the SMTP email

espocrm7

7. Installation Complete

espocrm8

It is very easy right ? 🙂 hehehehe.  I was very helped with this aaPanel as my control panel, because i didnt any touch ssh to remote and do some shell scripting as well. All i do from creating Web Server, Database, the website, and also deploy the application i did it within this web control, and also after that i also did some Cron job like backup site and database it is easy all within GUI.

Here the user interface, Espro when we already login.

espocrm10

 

 

 

Power Automate, Try Catch Block

When i was on develop Request Money workflow using Power Automate. You can read on this link : https://agustox21.wordpress.com/2020/07/17/solution-show-caserequest-money-goods-approval-using-office-365-power-apps-and-ms-automate/.

I was have a problem where there is data that sometimes appears and sometime not and i have to get the value for that.

At that time, i am struggle on data result from block Get Items to Sharepoint List on Power Automate. If field Manager or Manager 2 has value, then we can get the value from each of field. But if not, the data it will not shown so it is need to double check it because it will error if using the same function to get the value

I tried to find the validation script for that but until now still not find yet and then i found that Power Automate has block function about Try Catch then i decided to use it

Try, Catch, Finally blocks in the above template are nothing but scope controls

 

Here below is the use of scope in my Power Automate :

Try – The “Try” scope should contain all the actions from the main flow of the process.

 

Catch – The “Catch” scope is configured to run after “Try” block is failed. This is implemented using “Configure run after ” feature .

image-15

image-16

 

Happy Sharepoint-Ing

Solution Show Case:Request Money/Goods Approval using Office 365, Power Apps, and Power Automate

This is our second Solution Show Case, about Workflow Request Money/Goods Approval. Our first Solution Show case you can see on this link https://agustox21.wordpress.com/2020/06/01/room-booking-reservation-integration-with-sharepoint-365-power-apps-power-automate-and-ics-file/ .

To all our Office 365 clients, we will provide this for free and can be changed according to client needs.

Here are the details for this projects :

  1. Business Process
  • All user that have access to that site able to create new Request Money/Goods.
  • Once submiteed, automatically triggered Power Automate and Get data approval from Organization List base on the Requestor
  • If Requestor not yet have data on the Organization List, it will send email to Requestor the Approval Rejected
  • And If Request have data on Organization List, the approval will continue

2. Power Automate

3. List Organization

4. List Request Money/Goods

5. Request Money/Goods using Power Apps .

You can accessing the form through Sharepoint site and you can also accessing through mobile device if you already installed Power Apps application.

6. Approval Through Email

7. Notification through Email when Approval Completed

Happy Sharepoint-Ing

How to Benchmark VM Ubuntu (CPU, File IO,Memory, MySQL) with Sysbench

Sysbench is a mutli-purpose benchmark that features tests for CPU, memory, I/O, and even database performance testing. It’s a basic command line utility that offers a direct and uncomplicated way to test your system.

1. Install Sysbench on Ubuntu

sudo apt-get update
sudo apt install sysbench

2. CPU Benchmark

sysbench --test=cpu --cpu-max-prime=20000 run

3. File I/O Benchmark

To measure file IO performance, we first need to create a test file that is much bigger than your RAM (because otherwise, the system will use RAM for caching which tampers with the benchmark results) – 150GB is a good value:
Sysbench --test=fileio --file-total-size=150G prepare

Afterwards, we can run the benchmark:

sysbench --test=fileio --file-total-size=150G --file-test-mode=rndrw --init-rng=on --max-time=300 --max-requests=0 run

sysbench --test=fileio --file-total-size=150G cleanup

4. Memory Benchmark

sysbench --test=memory run 

5. MySQL Benchmark

To measure MySQL performance, we first create a test table in the database test with 1,000,000 rows of data:
sysbench --test=oltp --oltp-table-size=1000000 --db-driver=mysql --mysql-db=test --mysql-user=root --mysql-password=yourrootsqlpassword prepare
root@server1:~# sysbench --test=oltp --oltp-table-size=1000000 --db-driver=mysql --mysql-db=test --mysql-user=root --mysql-password=yourrootsqlpassword prepare
sysbench 0.4.12: multi-threaded system evaluation benchmark

Afterwards, we can run the benchmark:

sysbench --test=oltp --oltp-table-size=1000000 --db-driver=mysql --mysql-db=test --mysql-user=root --mysql-password=yourrootsqlpassword --max-time=60 --oltp-read-only=on --max-requests=0 --num-threads=8 run

To clean up the system afterwards (i.e., remove the test table), run:

sysbench --test=oltp --db-driver=mysql --mysql-db=test --mysql-user=root --mysql-password=yourrootsqlpassword cleanup

How to get count/length on Filter Array function when query into Sharepoint List items using Ms Automate

Hola,

I have a scenario project that need to query from my Organization contact list which if the requestor create a new request then the approval which triggered from Microsoft Automate / Flow then approval users it will taken from my Organization contact list

The Organization Contact List schema :

The MS Flow Process as below :

length(Body(‘Filter_array’)) : this is the function that i am need to get total my query from result Filter Array.

Happy Sharepoint-ing

Change Default SSH Port in Ubuntu

By default SSH Port uses port number 22. But if you want to change the default SSH port in Ubuntu, perform the following steps with root privileges:

  1. Open the /etc/ssh/sshd_config file and locate the line #Port 22
sudo nano /etc/ssh/sshd_config

2. Then, uncomment (Remove the leading # character) it and change the value with an appropriate port number (for example, 4022) then save the configuration

3. Restart service SSH

systemctl restart sshd

Convert HTML String To PDF Via iText Library And Download

I decided post this code in this blog for my reference later if i go back again as Developer 🙂 This Project was a Sharepoint 2016 Project and still used web form asp.net application.

  1. Code the ascx (Usercontrol)

When the user is directed to this page, the user control automatically creates some html data regarding the information sent. Then after information are done, if you check on javascript code below, #btnprint triger to click and that button and execute javascript function PrintElem.

The PrintElem function is to collect the HTML code (see on the var printContents) then transfer to control txtPrint. After are done then call server side function btnExportToPdf_Click (__doPostBack(‘<%=btnExportToPdf.UniqueID%>’, ”);)

2. Reference library

HtmlAgilityPack and iText 7, you can download it from manage nuget on your visual studio.

3. Code

protected void btnExportToPdf_Click(object sender, EventArgs e)
{
StringBuilder contents = new StringBuilder(txtPrint.Text);
string mFilePath = string.Empty;

        //fungsi di bawah hanya untuk mendapatkan jumlah page
        using (MemoryStream ms = new MemoryStream())
        {
            HtmlDocument hDocument = new HtmlDocument
            {
                OptionWriteEmptyNodes = true,
                OptionAutoCloseOnEnd = true,
            };

            hDocument.LoadHtml(contents.ToString());
            var closedTags = hDocument.DocumentNode.WriteTo();

            FontProgram fontProgram = FontProgramFactory.CreateFont(@"C:\Windows\Fonts\calibri.ttf");
            PdfFont calibri = PdfFontFactory.CreateFont(fontProgram, PdfEncodings.WINANSI);

            iText.Kernel.Pdf.PdfWriter pdfWriter = new PdfWriter(ms);
            PdfDocument pdfDocument = new PdfDocument(pdfWriter);
            pdfDocument.AddFont(calibri);

            iText.Kernel.Pdf.PdfDocument pdfDoc = new iText.Kernel.Pdf.PdfDocument(pdfWriter);
            pdfDoc.SetDefaultPageSize(iText.Kernel.Geom.PageSize.A4);

            HeadertFooterHandler handler = new HeadertFooterHandler();
            pdfDoc.AddEventHandler(PdfDocumentEvent.START_PAGE, handler);
            handler.setInfo(DocNo);

            using (Document document = new Document(pdfDoc))
            {
                /*document.SetMargins(10, 10, 10, 10);*/
                document.SetMargins(0, 0, 0, 0);
                document.SetFont(calibri);
                document.SetFontSize(8);
                document.SetWordSpacing(0);

                using (var htmlMemoryStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(closedTags.ToString())))
                {
                    /* KB : https://itextpdf.com/en/resources/books/itext-7-converting-html-pdf-pdfhtml/chapter-6-using-fonts-pdfhtml */

                    ConverterProperties properties = new ConverterProperties();
                    properties.SetFontProvider(new iText.Html2pdf.Resolver.Font.DefaultFontProvider(true, true, true));

                    HtmlConverter.ConvertToPdf(htmlMemoryStream, pdfDoc, properties);
                }
            }

            //byte[] mByte = ms.ToArray();

            //TR_AFA_HEADERS afa = AfaHeader;
            //mFilePath = string.Format("{0}/{1}/{2}/AFA_{3}_Print.pdf", SPContext.Current.Web.Url, afa.DocumentLibraryType, afa.AfaHeaderID, afa.Afa_Header_Id);

            //bool sts = Utils.SP_UploadDocument(SPContext.Current.Web.Url, mFilePath, mByte, afa.Afa_Number, afa.Afa_Purpose);

            contents = null;

            pdfDoc.Close();
            pdfWriter.Close();
            ms.Close();
        }

        using (MemoryStream ms = new MemoryStream())
        {
            HtmlDocument hDocument = new HtmlDocument
            {
                OptionWriteEmptyNodes = true,
                OptionAutoCloseOnEnd = true,
            };

            hDocument.LoadHtml(contents.ToString());
            var closedTags = hDocument.DocumentNode.WriteTo();

            FontProgram fontProgram = FontProgramFactory.CreateFont(@"C:\Windows\Fonts\calibri.ttf");
            PdfFont calibri = PdfFontFactory.CreateFont(fontProgram, PdfEncodings.WINANSI);

            iText.Kernel.Pdf.PdfWriter pdfWriter = new PdfWriter(ms);
            PdfDocument pdfDocument = new PdfDocument(pdfWriter);
            pdfDocument.AddFont(calibri);

            iText.Kernel.Pdf.PdfDocument pdfDoc = new iText.Kernel.Pdf.PdfDocument(pdfWriter);
            pdfDoc.SetDefaultPageSize(iText.Kernel.Geom.PageSize.A4);

            HeadertFooterHandler handler = new HeadertFooterHandler();
            pdfDoc.AddEventHandler(PdfDocumentEvent.START_PAGE, handler);
            handler.setInfo(DocNo);

            using (Document document = new Document(pdfDoc))
            {
                /*document.SetMargins(10, 10, 10, 10);*/
                document.SetMargins(0, 0, 0, 0);
                document.SetFont(calibri);
                document.SetFontSize(8);
                document.SetWordSpacing(0);

                using (var htmlMemoryStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(closedTags.ToString())))
                {
                    /* KB : https://itextpdf.com/en/resources/books/itext-7-converting-html-pdf-pdfhtml/chapter-6-using-fonts-pdfhtml */

                    ConverterProperties properties = new ConverterProperties();
                    properties.SetFontProvider(new iText.Html2pdf.Resolver.Font.DefaultFontProvider(true, true, true));

                    HtmlConverter.ConvertToPdf(htmlMemoryStream, pdfDoc, properties);
                }
            }

            byte[] mByte = ms.ToArray();

            TR_AFA_HEADERS afa = AfaHeader;
            mFilePath = string.Format("{0}/{1}/{2}/AFA_{3}_Print.pdf", SPContext.Current.Web.Url, afa.DocumentLibraryType, afa.AfaHeaderID, afa.Afa_Header_Id);

            bool sts = Utils.SP_UploadDocument(SPContext.Current.Web.Url, mFilePath, mByte, afa.Afa_Number, afa.Afa_Purpose);

            contents = null;

            pdfDoc.Close();
            pdfWriter.Close();
            ms.Close();
        }
        loading_screen.Attributes.Add("style", "display:none");
        Response.Redirect(mFilePath);
    }


}

public class HeadertFooterHandler : IEventHandler
{
    String info;
    public void setInfo(String info)
    {
        this.info = info;
    }
    public String getInfo()
    {
        return info;
    }

    public void HandleEvent(Event @event)
    {
        iText.Kernel.Colors.Color colorGray = new DeviceRgb(128, 128, 128);

        PdfDocumentEvent docEvent = (PdfDocumentEvent)@event;
        PdfPage page = docEvent.GetPage();
        int pageNum = docEvent.GetDocument().GetPageNumber(page);

        iText.Kernel.Geom.Rectangle pageSize = page.GetPageSize();
        PdfDocument pdfDoc = ((PdfDocumentEvent)@event).GetDocument();

        PdfCanvas pdfCanvas = new PdfCanvas(page.NewContentStreamBefore(), page.GetResources(), pdfDoc);

        new Canvas(pdfCanvas, pdfDoc, pageSize)
         //header
         .SetFontSize(4)
         .SetOpacity(2)
         .SetFontColor(colorGray)
         .ShowTextAligned(info, 10, pageSize.GetTop() - 20, TextAlignment.LEFT, VerticalAlignment.MIDDLE, 0)
         .ShowTextAligned(string.Format("{0:dd MMM yyyy HH:mm:ss}", DateTime.Now), 10, 30, TextAlignment.LEFT, VerticalAlignment.MIDDLE, 0)
         .ShowTextAligned(string.Format("Page {0} of {1}",pageNum.ToString(), docEvent.GetDocument().GetNumberOfPages()), pageSize.GetWidth() - 60, 30, TextAlignment.RIGHT, VerticalAlignment.MIDDLE, 0);
    }
}

Sample screenshot

Happy Sharepoint-ing