diff --git a/datapath-windows/automake.mk b/datapath-windows/automake.mk
index 3820041f6..d98ab3c60 100644
--- a/datapath-windows/automake.mk
+++ b/datapath-windows/automake.mk
@@ -3,6 +3,7 @@ EXTRA_DIST += \
 	datapath-windows/Package/package.VcxProj.user \
 	datapath-windows/include/OvsDpInterfaceExt.h \
 	datapath-windows/include/OvsDpInterfaceCtExt.h \
+	datapath-windows/misc/HNSHelper.psm1 \
 	datapath-windows/misc/OVS.psm1 \
 	datapath-windows/misc/install.cmd \
 	datapath-windows/misc/uninstall.cmd \
diff --git a/datapath-windows/misc/HNSHelper.psm1 b/datapath-windows/misc/HNSHelper.psm1
new file mode 100644
index 000000000..ac99889cf
--- /dev/null
+++ b/datapath-windows/misc/HNSHelper.psm1
@@ -0,0 +1,499 @@
+# SDN Sample Scripts  v.1.0
+#
+# Copyright (c) Microsoft Corporation
+#
+# All rights reserved. 
+#
+# MIT License
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the ""Software""), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+#########################################################################
+# Global Initialize
+function Get-VmComputeNativeMethods()
+{
+        $signature = @'
+                     [DllImport("vmcompute.dll")]
+                     public static extern void HNSCall([MarshalAs(UnmanagedType.LPWStr)] string method, [MarshalAs(UnmanagedType.LPWStr)] string path, [MarshalAs(UnmanagedType.LPWStr)] string request, [MarshalAs(UnmanagedType.LPWStr)] out string response);
+'@
+
+    # Compile into runtime type
+    try { return [VmCompute.PrivatePInvoke.NativeMethods] }
+    catch { return (Add-Type -MemberDefinition $signature -Namespace VmCompute.PrivatePInvoke -Name NativeMethods -PassThru) }
+}
+
+#########################################################################
+# Configuration
+#########################################################################
+function Get-HnsSwitchExtensions
+{
+    param
+    (
+        [parameter(Mandatory=$true)] [string] $NetworkId
+    )
+
+    return (Get-HNSNetwork $NetworkId).Extensions
+}
+
+function Set-HnsSwitchExtension
+{
+    param
+    (
+        [parameter(Mandatory=$true)] [string] $NetworkId,
+        [parameter(Mandatory=$true)] [string] $ExtensionId,
+        [parameter(Mandatory=$true)] [bool]   $state
+    )
+
+    # { "Extensions": [ { "Id": "...", "IsEnabled": true|false } ] }
+    $req = @{
+        "Extensions"=@(@{
+            "Id"=$ExtensionId;
+            "IsEnabled"=$state;
+        };)
+    }
+    Invoke-HNSRequest -Method POST -Type networks -Id $NetworkId -Data (ConvertTo-Json $req)
+}
+
+#########################################################################
+# Activities
+#########################################################################
+function Get-HNSActivities
+{
+    [cmdletbinding()]Param()
+    return Invoke-HNSRequest -Type activities -Method GET
+}
+
+#########################################################################
+# PolicyLists
+#########################################################################
+function Get-HNSPolicyList {
+    [cmdletbinding()]Param()
+    return Invoke-HNSRequest -Type policylists -Method GET
+}
+
+function Remove-HnsPolicyList
+{
+    [CmdletBinding()]
+    param
+    (
+        [parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)]
+        [Object[]] $InputObjects
+    )
+    begin {$Objects = @()}
+    process {$Objects += $InputObjects; }
+    end {
+        $Objects | foreach {  Invoke-HNSRequest -Method DELETE -Type  policylists -Id $_.Id }
+    }
+}
+
+function New-HnsRoute {
+    param
+    (
+        [parameter(Mandatory = $false)] [Guid[]] $Endpoints = $null,
+        [parameter(Mandatory = $true)] [string] $DestinationPrefix,
+        [parameter(Mandatory = $false)] [switch] $EncapEnabled
+    )
+
+    $policyLists = @{
+        References = @(
+            get-endpointReferences $Endpoints;
+        );
+        Policies   = @(
+            @{
+                Type = "ROUTE";
+                DestinationPrefix = $DestinationPrefix;
+                NeedEncap = $EncapEnabled.IsPresent;
+            }
+        );
+    }
+
+    Invoke-HNSRequest -Method POST -Type policylists -Data (ConvertTo-Json  $policyLists -Depth 10)
+}
+
+function New-HnsLoadBalancer {
+    param
+    (
+        [parameter(Mandatory = $false)] [Guid[]] $Endpoints = $null,
+        [parameter(Mandatory = $true)] [int] $InternalPort,
+        [parameter(Mandatory = $true)] [int] $ExternalPort,
+        [parameter(Mandatory = $false)] [string] $Vip
+    )
+
+    $policyLists = @{
+        References = @(
+            get-endpointReferences $Endpoints;
+        );
+        Policies   = @(
+            @{
+                Type = "ELB";
+                InternalPort = $InternalPort;
+                ExternalPort = $ExternalPort;
+                VIPs = @($Vip);
+            }
+        );
+    }
+
+    Invoke-HNSRequest -Method POST -Type policylists -Data ( ConvertTo-Json  $policyLists -Depth 10)
+}
+
+
+function get-endpointReferences {
+    param
+    (
+        [parameter(Mandatory = $true)] [Guid[]] $Endpoints = $null
+    )
+    if ($Endpoints ) {
+        $endpointReference = @()
+        foreach ($endpoint in $Endpoints)
+        {
+            $endpointReference += "/endpoints/$endpoint"
+        }
+        return $endpointReference
+    }
+    return @()
+}
+
+#########################################################################
+# Networks
+#########################################################################
+function New-HnsNetwork
+{
+    param
+    (
+        [parameter(Mandatory=$false, Position=0)]
+        [string] $JsonString,
+        [ValidateSet('ICS', 'Internal', 'Transparent', 'NAT', 'Overlay', 'L2Bridge', 'L2Tunnel', 'Layered', 'Private')]
+        [parameter(Mandatory = $false, Position = 0)]
+        [string] $Type,
+        [parameter(Mandatory = $false)] [string] $Name,
+        [parameter(Mandatory = $false)] [string] $AddressPrefix,
+        [parameter(Mandatory = $false)] [string] $Gateway,
+        [parameter(Mandatory = $false)] [string] $DNSServer,
+        [parameter(Mandatory = $false)] [string] $AdapterName
+    )
+
+    Begin {
+        if (!$JsonString) {
+            $netobj = @{
+                Type          = $Type;
+            };
+
+            if ($Name) {
+                $netobj += @{
+                    Name = $Name;
+                }
+            }
+
+            if ($AddressPrefix -and  $Gateway) {
+                $netobj += @{
+                    Subnets = @(
+                        @{
+                            AddressPrefix  = $AddressPrefix;
+                            GatewayAddress = $Gateway;
+                        }
+                    );
+                }
+            }
+
+            if ($DNSServerName) {
+                $netobj += @{
+                    DNSServerList = $DNSServer
+                }
+            }
+
+            if ($AdapterName) {
+                $netobj += @{
+                    NetworkAdapterName = $AdapterName;
+                }
+            }
+
+            $JsonString = ConvertTo-Json $netobj -Depth 10
+        }
+
+    }
+    Process{
+        return Invoke-HNSRequest -Method POST -Type networks -Data $JsonString
+    }
+}
+
+#########################################################################
+# Endpoints
+#########################################################################
+function New-HnsEndpoint
+{
+    param
+    (
+        [parameter(Mandatory=$false, Position = 0)] [string] $JsonString = $null,
+        [parameter(Mandatory = $false, Position = 0)] [Guid] $NetworkId,
+        [parameter(Mandatory = $false)] [string] $Name,
+        [parameter(Mandatory = $false)] [string] $IPAddress,
+        [parameter(Mandatory = $false)] [string] $Gateway,
+        [parameter(Mandatory = $false)] [string] $MacAddress,
+        [parameter(Mandatory = $false)] [switch] $EnableOutboundNat
+    )
+
+    begin
+    {
+        if ($JsonString)
+        {
+            $EndpointData = $JsonString | ConvertTo-Json | ConvertFrom-Json
+        }
+        else
+        {
+            $endpoint = @{
+                VirtualNetwork = $NetworkId;
+                Policies       = @();
+            }
+
+            if ($Name) {
+                $endpoint += @{
+                    Name = $Name;
+                }
+            }
+
+            if ($MacAddress) {
+                $endpoint += @{
+                    MacAddress     = $MacAddress;
+                }
+            }
+
+            if ($IPAddress) {
+                $endpoint += @{
+                    IPAddress      = $IPAddress;
+                }
+            }
+
+            if ($Gateway) {
+                $endpoint += @{
+                    GatewayAddress = $Gateway;
+                }
+            }
+
+            if ($EnableOutboundNat) {
+                $endpoint.Policies += @{
+                    Type = "OutBoundNAT";
+                }
+
+            }
+            # Try to Generate the data
+            $EndpointData = convertto-json $endpoint
+        }
+    }
+
+    Process
+    {
+        return Invoke-HNSRequest -Method POST -Type endpoints -Data $EndpointData
+    }
+}
+
+
+function New-HnsRemoteEndpoint
+{
+    param
+    (
+        [parameter(Mandatory = $true)] [Guid] $NetworkId,
+        [parameter(Mandatory = $false)] [string] $IPAddress,
+        [parameter(Mandatory = $false)] [string] $MacAddress
+    )
+
+    $remoteEndpoint = @{
+        ID = [Guid]::NewGuid();
+        VirtualNetwork = $NetworkId;
+        IPAddress = $IPAddress;
+        MacAddress = $MacAddress;
+        IsRemoteEndpoint = $true;
+    }
+
+    return Invoke-HNSRequest -Method POST -Type endpoints -Data (ConvertTo-Json $remoteEndpoint  -Depth 10)
+
+}
+
+
+function Attach-HnsHostEndpoint
+{
+    param
+    (
+     [parameter(Mandatory=$true)] [Guid] $EndpointID,
+     [parameter(Mandatory=$true)] [int] $CompartmentID
+     )
+    $request = @{
+        SystemType    = "Host";
+        CompartmentId = $CompartmentID;
+    };
+
+    return Invoke-HNSRequest -Method POST -Type endpoints -Data (ConvertTo-Json $request) -Action "attach" -Id $EndpointID
+}
+
+function Attach-HNSVMEndpoint
+{
+    param
+    (
+     [parameter(Mandatory=$true)] [Guid] $EndpointID,
+     [parameter(Mandatory=$true)] [string] $VMNetworkAdapterName
+     )
+
+    $request = @{
+        VirtualNicName   = $VMNetworkAdapterName;
+        SystemType    = "VirtualMachine";
+    };
+    return Invoke-HNSRequest -Method POST -Type endpoints -Data (ConvertTo-Json $request ) -Action "attach" -Id $EndpointID
+
+}
+
+function Attach-HNSEndpoint
+{
+    param
+    (
+        [parameter(Mandatory=$true)] [Guid] $EndpointID,
+        [parameter(Mandatory=$true)] [int] $CompartmentID,
+        [parameter(Mandatory=$true)] [string] $ContainerID
+    )
+     $request = @{
+        ContainerId = $ContainerID;
+        SystemType="Container";
+        CompartmentId = $CompartmentID;
+    };
+
+    return Invoke-HNSRequest -Method POST -Type endpoints -Data (ConvertTo-Json $request) -Action "attach" -Id $EndpointID
+}
+
+function Detach-HNSVMEndpoint
+{
+    param
+    (
+        [parameter(Mandatory=$true)] [Guid] $EndpointID
+    )
+    $request = @{
+        SystemType  = "VirtualMachine";
+    };
+
+    return Invoke-HNSRequest -Method POST -Type endpoints -Data (ConvertTo-Json $request ) -Action "detach" -Id $EndpointID
+}
+
+function Detach-HNSHostEndpoint
+{
+    param
+    (
+        [parameter(Mandatory=$true)] [Guid] $EndpointID
+    )
+    $request = @{
+        SystemType  = "Host";
+    };
+
+    return Invoke-HNSRequest -Method POST -Type endpoints -Data (ConvertTo-Json $request ) -Action "detach" -Id $EndpointID
+}
+
+function Detach-HNSEndpoint
+{
+    param
+    (
+        [parameter(Mandatory=$true)] [Guid] $EndpointID,
+        [parameter(Mandatory=$true)] [string] $ContainerID
+    )
+
+    $request = @{
+        ContainerId = $ContainerID;
+        SystemType="Container";
+    };
+
+    return Invoke-HNSRequest -Method POST -Type endpoints -Data (ConvertTo-Json $request ) -Action "detach" -Id $EndpointID
+}
+#########################################################################
+
+function Invoke-HNSRequest
+{
+    param
+    (
+        [ValidateSet('GET', 'POST', 'DELETE')]
+        [parameter(Mandatory=$true)] [string] $Method,
+        [ValidateSet('networks', 'endpoints', 'activities', 'policylists', 'endpointstats', 'plugins')]
+        [parameter(Mandatory=$true)] [string] $Type,
+        [parameter(Mandatory=$false)] [string] $Action = $null,
+        [parameter(Mandatory=$false)] [string] $Data = $null,
+        [parameter(Mandatory=$false)] [Guid] $Id = [Guid]::Empty
+    )
+
+    $hnsPath = "/$Type"
+
+    if ($id -ne [Guid]::Empty)
+    {
+        $hnsPath += "/$id";
+    }
+
+    if ($Action)
+    {
+        $hnsPath += "/$Action";
+    }
+
+    $request = "";
+    if ($Data)
+    {
+        $request = $Data
+    }
+
+    $output = "";
+    $response = "";
+    Write-Verbose "Invoke-HNSRequest Method[$Method] Path[$hnsPath] Data[$request]"
+
+    $hnsApi = Get-VmComputeNativeMethods
+    $hnsApi::HNSCall($Method, $hnsPath, "$request", [ref] $response);
+
+    Write-Verbose "Result : $response"
+    if ($response)
+    {
+        try {
+            $output = ($response | ConvertFrom-Json);
+        } catch {
+            Write-Error $_.Exception.Message
+            return ""
+        }
+        if ($output.Error)
+        {
+             Write-Error $output;
+        }
+        $output = $output.Output;
+    }
+
+    return $output;
+}
+
+#########################################################################
+
+Export-ModuleMember -Function Get-HNSActivities
+Export-ModuleMember -Function Get-HnsSwitchExtensions
+Export-ModuleMember -Function Set-HnsSwitchExtension
+
+Export-ModuleMember -Function New-HNSNetwork
+
+Export-ModuleMember -Function New-HNSEndpoint
+Export-ModuleMember -Function New-HnsRemoteEndpoint
+
+Export-ModuleMember -Function Attach-HNSHostEndpoint
+Export-ModuleMember -Function Attach-HNSVMEndpoint
+Export-ModuleMember -Function Attach-HNSEndpoint
+Export-ModuleMember -Function Detach-HNSHostEndpoint
+Export-ModuleMember -Function Detach-HNSVMEndpoint
+Export-ModuleMember -Function Detach-HNSEndpoint
+
+Export-ModuleMember -Function Get-HNSPolicyList
+Export-ModuleMember -Function Remove-HnsPolicyList
+Export-ModuleMember -Function New-HnsRoute
+Export-ModuleMember -Function New-HnsLoadBalancer
+
+Export-ModuleMember -Function Invoke-HNSRequest
diff --git a/datapath-windows/misc/OVS.psm1 b/datapath-windows/misc/OVS.psm1
index a8ffcaefd..1cc347bc6 100644
--- a/datapath-windows/misc/OVS.psm1
+++ b/datapath-windows/misc/OVS.psm1
@@ -207,4 +207,81 @@ function Set-VMNetworkAdapterOVSPortDirect
     }
 }
 
-Export-ModuleMember -function Set-*, Get-*
+function Get-OVSEnabledHNSNetworks
+{
+    return (Get-HNSNetwork) | Where-Object {($_.Extensions.Id -eq '583cc151-73ec-4a6a-8b47-578297ad7623') -and ($_.Extensions.IsEnabled -eq 'True')}
+}
+
+function Add-OVSHNSInternalPort
+{
+    param
+    (
+        [parameter(Mandatory=$true)] [string] $PortName
+    )
+    $test = [array](Get-NetAdapter -IncludeHidden -InterfaceAlias "$PortName" -ErrorAction SilentlyContinue)
+    if (!($test -eq $null))
+    {
+        return
+    }
+    $test = [array]((Get-HnsEndpoint) | Where-Object {($_.Name -eq "$PortName")})
+    if (!($test -eq $null))
+    {
+        return
+    }
+    $a = [array](Get-OVSEnabledHNSNetworks).Id
+    if ($a.count -eq 0)
+    {
+        # If we did not find any OVS enabled switches try to find the ID via
+        # environment variable
+        $a = [array]$env:OVS_ENABLED_NETWORK_ID
+        if ($a.count -eq 0)
+        {
+            # Bypass 1803 listing bug and assumed that the first transparent
+            # network is OVS enabled
+            $a = [array](Get-HNSNetwork | where {$_.type -eq "transparent"}).ID
+            if ($a.count -eq 0)
+            {
+                return
+            }
+        }
+    }
+    $temp = New-HnsEndpoint -NetworkId $a[0] -Name "$PortName"
+    Attach-HnsHostEndpoint $temp.Id 1
+    Rename-NetAdapter -IncludeHidden -InterfaceAlias "vEthernet ($PortName)" -NewName "$PortName" -ErrorAction SilentlyContinue
+    Remove-NetRoute -InterfaceAlias "$PortName" -Confirm:$false -ErrorAction SilentlyContinue
+    Disable-NetAdapter -Confirm:$false -IncludeHidden -InterfaceAlias "$PortName" -ErrorAction SilentlyContinue
+}
+
+function Delete-OVSHNSInternalPort
+{
+    param
+    (
+        [parameter(Mandatory=$true)] [string] $PortName
+    )
+    $a = [array]((Get-HnsEndpoint) | Where-Object {($_.Name -eq "$PortName")})
+    $request = @{
+        SystemType  = "Host";
+    };
+
+    return Invoke-HNSRequest -Method DELETE -Type endpoints -Data (ConvertTo-Json $request ) -Id $a[0].ID
+}
+
+function Enable-OVSOnHNSNetwork
+{
+    param
+    (
+        [parameter(Mandatory=$true)] [string] $NetworkId
+    )
+    return Set-HnsSwitchExtension -NetworkId $NetworkId -ExtensionId 583cc151-73ec-4a6a-8b47-578297ad7623 -state $True
+}
+
+function Disable-OVSOnHNSNetwork
+{
+    param
+    (
+        [parameter(Mandatory=$true)] [string] $NetworkId
+    )
+    return Set-HnsSwitchExtension -NetworkId $NetworkId -ExtensionId 583cc151-73ec-4a6a-8b47-578297ad7623 -state $False
+}
+
+Export-ModuleMember -function Set-*, Get-*, Enable-*, Disable-*, Add-*, Delete-*
