locked
Powershell Errors RRS feed

  • Question

  • I have been following the Microsoft guide for setting up AlwaysOnVPN and having problems running the following script. 

    https://docs.microsoft.com/en-us/windows-server/remote/remote-access/vpn/always-on-vpn/deploy/vpn-deploy-client-vpn-connections#bkmk_fullscript

    I have customised the custom elements at the start but i am getting the following errors any one got any ideas. 

    At C:\build\MakeProfile.ps1:47 char:48
    +  $ProfileNameEscaped = $ProfileName -replace ' ', '%20'
    +                                                ~~~~
    Unexpected token '', '' in expression or statement.
    At C:\build\MakeProfile.ps1:47 char:53
    +  $ProfileNameEscaped = $ProfileName -replace ' ', '%20'
    +                                                     ~
    You must provide a value expression following the '%' operator.
    At C:\build\MakeProfile.ps1:47 char:53
    +  $ProfileNameEscaped = $ProfileName -replace ' ', '%20'
    +                                                     ~~~
    Unexpected token '20'
     $ProfileXML = '''' in expression or statement.
    At C:\build\MakeProfile.ps1:51 char:38
    +  $ProfileXML = $ProfileXML -replace '<', '&lt;'
    +                                      ~
    The '<' operator is reserved for future use.
    At C:\build\MakeProfile.ps1:51 char:43
    +  $ProfileXML = $ProfileXML -replace '<', '&lt;'
    +                                           ~
    The ampersand (&) character is not allowed. The & operator is reserved for future use; wrap an ampersand in double quotation marks ("&") to 
    pass it as part of a string.
    At C:\build\MakeProfile.ps1:52 char:43
    +  $ProfileXML = $ProfileXML -replace '>', '&gt;'
    +                                           ~
    Unexpected token '&' in expression or statement.
    At C:\build\MakeProfile.ps1:53 char:38
    +  $ProfileXML = $ProfileXML -replace '"', '&quot;'
    +                                      ~~~~~~~~~~~~
    Unexpected token '"', '&quot;'
     $nodeCSPURI = "' in expression or statement.
    At C:\build\MakeProfile.ps1:55 char:18
    +  $nodeCSPURI = "./Vendor/MSFT/VPNv2"
    +                  ~
    Missing property name after reference operator.
    At C:\build\MakeProfile.ps1:65 char:19
    +  $Message = "User SID is $SidValue."
    +                   ~~~
    Unexpected token 'SID' in expression or statement.
    At C:\build\MakeProfile.ps1:131 char:22
    +  Write-Host "$Message"
    +                      ~
    The string is missing the terminator: ".
        + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
        + FullyQualifiedErrorId : UnexpectedToken

    Tuesday, January 29, 2019 3:06 PM

All replies

  • We cannot modify scripts you have copied for you.  You will need to contact a consultant to help you with this.


    \_(ツ)_/

    Tuesday, January 29, 2019 3:13 PM
  • The first error is generally the one to fix. You probably have unbalanced quotes, causing all subsequent errors.

    Richard Mueller - MVP Enterprise Mobility (Identity and Access)

    Tuesday, January 29, 2019 3:15 PM
  • I took  look at the script. It is loaded with errors and syntax issues.  It is a very badly written script.


    \_(ツ)_/

    Tuesday, January 29, 2019 3:19 PM
  • If you read the comments on the article it is clear that no one can make any of it work.

    The person who wrote the code does not have a clue about writing PowerShell scripts.  The XML should be built using the XML classes.  Allof gthe string operations could be eliminated very easily.

    Here is a partial fix but many items are  missing so more work is needed.  I removed most of the bad characters and the extra spaces.  The code was broken, in part, because it was badly pasted into the web page.

    function New-VMProfile{
        
        $TemplateName = 'Template'
        $ProfileName = 'Contoso AlwaysOn VPN'
        $Servers = 'vpn.contoso.com'
        $DnsSuffix = 'corp.contoso.com'
        $DomainName = '.corp.contoso.com'
        $DNSServers = '10.10.0.2,10.10.0.3'
        $TrustedNetwork = 'corp.contoso.com'
        
        Try{
            $Connection = Get-VpnConnection -Name $TemplateName -ErrorAction Stop
        }
        Catch{
            Write-Host "Unable to get $TemplateName connection profile: $_"
            return
        }
        
        $EAPSettings = $Connection.EapConfigXmlStream.InnerXml
    
    $ProfileXML = @'
        <VPNProfile>
           <DnsSuffix>{0}</DnsSuffix>
           <NativeProfile>
                <Servers>{1}</Servers>
                <NativeProtocolType>IKEv2</NativeProtocolType>
                <Authentication>
                    <UserMethod>Eap</UserMethod>
                    <Eap>
                        <Configuration>{2}</Configuration>
                    </Eap>
                </Authentication>
                <RoutingPolicyType>SplitTunnel</RoutingPolicyType>
            </NativeProfile>
            <AlwaysOn>true</AlwaysOn>
            <RememberCredentials>true</RememberCredentials>
            <TrustedNetworkDetection>{3}</TrustedNetworkDetection>
            <DomainNameInformation>
                <DomainName>{4}</DomainName>
                <DnsServers>{5}</DnsServers>
            </DomainNameInformation>
        </VPNProfile>
    '@ -f $DnsSuffix, $Servers, $EAPSettings, $TrustedNetwork, $DomainName, $DNSServers
    
    
        $ProfileXML = ''' + $ProfileXML + '''
        $ProfileXML = $ProfileXML -replace '<', '&lt;'
        $ProfileXML = $ProfileXML -replace '>', '&gt;'
        $ProfileXML = $ProfileXML -replace '"', '&quot;'
        $ProfileXML | Out-File -FilePath ($env:USERPROFILE + '\desktop\VPN_Profile.xml')
        $ProfileNameEscaped = $ProfileName -replace ' ', '%20'
        
        Try{
            $username = Get-WmiObject -Class Win32_ComputerSystem | select username
            $objuser = New-Object System.Security.Principal.NTAccount($username.username)
            $sid = $objuser.Translate([System.Security.Principal.SecurityIdentifier])
            $SidValue = $sid.Value
            $Message = "User SID is $SidValue."
            Write-Host "$Message"
        }
        Catch{
            Write-Host "Unable to get user SID. User may be logged on over Remote Desktop: $_"
            exit
        }
    
        $session = New-CimSession
        $options = New-Object Microsoft.Management.Infrastructure.Options.CimOperationOptions
        $options.SetCustomOption('PolicyPlatformContext_PrincipalContext_Type', 'PolicyPlatform_UserContext', $false)
        $options.SetCustomOption('PolicyPlatformContext_PrincipalContext_Id', $SidValue, $false)
    
        try{
             $deleteInstances = $session.EnumerateInstances($namespaceName, $className, $options)
             foreach ($deleteInstance in $deleteInstances){
                 $InstanceId = $deleteInstance.InstanceID
                 if ("$InstanceId" -eq "$ProfileNameEscaped")             {
                     $session.DeleteInstance($namespaceName, $deleteInstance, $options)
                     $Message = "Removed $ProfileName profile $InstanceId"
                     Write-Host "$Message"
                 } else {
                     $Message = "Ignoring existing VPN profile $InstanceId"
                     Write-Host "$Message"
                 }
             }
         }
         catch{
             Write-Host "Unable to remove existing outdated instance(s) of $ProfileName profile: $_"
    return } try{ $newInstance = New-Object Microsoft.Management.Infrastructure.CimInstance './Vendor/MSFT/VPNv2', 'root\cimv2\mdm\dmmap' $property = [Microsoft.Management.Infrastructure.CimProperty]::Create('ParentID', '$nodeCSPURI', 'String', 'Key') $newInstance.CimInstanceProperties.Add($property) $property = [Microsoft.Management.Infrastructure.CimProperty]::Create('InstanceID', '$ProfileNameEscaped', 'String', 'Key') $newInstance.CimInstanceProperties.Add($property) $property = [Microsoft.Management.Infrastructure.CimProperty]::Create('ProfileXML', '$ProfileXML', 'String', 'Property') $newInstance.CimInstanceProperties.Add($property) $session.CreateInstance('root\cimv2\mdm\dmmap', $newInstance, $options) Write-Host 'Created $ProfileName profile.' } catch{ Write-Host "Unable to create $ProfileName profile: $_" return } $Script | Out-File -FilePath ($env:USERPROFILE + '\desktop\VPN_Profile.ps1') Write-Host "Successfully created VPN_Profile.xml and VPN_Profile.ps1 on the desktop." }

    Look on the net for  version of this that works.


    \_(ツ)_/




    • Edited by jrv Tuesday, January 29, 2019 3:56 PM
    Tuesday, January 29, 2019 3:53 PM
  • So why is this published on The Official Microsoft Website for customers to use?

    Tuesday, January 29, 2019 3:56 PM
  • Because Microsoft like to make work for junior programmers.  Sometimes they don't review the work.

    Here is a copy that is ready to debug.  The script generation piece needs to be written correctly and the XML piece needs to be converted to all XML.

    Fell free to start the debugging.  Don't wait for me.  I am going to lunch and have other things to do.

    function New-VMProfile{
        [CmdletBinding()]
        $TemplateName = 'Template'
        $ProfileName = 'Contoso AlwaysOn VPN'
        $Servers = 'vpn.contoso.com'
        $DnsSuffix = 'corp.contoso.com'
        $DomainName = '.corp.contoso.com'
        $DNSServers = '10.10.0.2,10.10.0.3'
        $TrustedNetwork = 'corp.contoso.com'
        
        Try{
            $Connection = Get-VpnConnection -Name $TemplateName -ErrorAction Stop
        }
        Catch{
            Throw
            return
        }
        
        $EAPSettings = $Connection.EapConfigXmlStream.InnerXml
    
    $ProfileXML = @'
        <VPNProfile>
           <DnsSuffix>{0}</DnsSuffix>
           <NativeProfile>
                <Servers>{1}</Servers>
                <NativeProtocolType>IKEv2</NativeProtocolType>
                <Authentication>
                    <UserMethod>Eap</UserMethod>
                    <Eap>
                        <Configuration>{2}</Configuration>
                    </Eap>
                </Authentication>
                <RoutingPolicyType>SplitTunnel</RoutingPolicyType>
            </NativeProfile>
            <AlwaysOn>true</AlwaysOn>
            <RememberCredentials>true</RememberCredentials>
            <TrustedNetworkDetection>{3}</TrustedNetworkDetection>
            <DomainNameInformation>
                <DomainName>{4}</DomainName>
                <DnsServers>{5}</DnsServers>
            </DomainNameInformation>
        </VPNProfile>
    '@ -f $DnsSuffix, $Servers, $EAPSettings, $TrustedNetwork, $DomainName, $DNSServers
    
    
        $ProfileXML = ''' + $ProfileXML + '''
        $ProfileXML = $ProfileXML -replace '<', '&lt;'
        $ProfileXML = $ProfileXML -replace '>', '&gt;'
        $ProfileXML = $ProfileXML -replace '"', '&quot;'
        $ProfileXML | Out-File -FilePath ($env:USERPROFILE + '\desktop\VPN_Profile.xml')
        $ProfileNameEscaped = $ProfileName -replace ' ', '%20'
        
        Try{
            $user = [System.Security.Principal.NTAccount]::New("$env:USERDOMAIN\$env:USERNAME")
            $sid = $user.Translate([System.Security.Principal.SecurityIdentifier])
            $SidValue = $sid.Value
            Write-Verbose "User SID is $SidValue."
        }
        Catch{
            Throw
            return
        }
    
        $options = New-Object Microsoft.Management.Infrastructure.Options.CimOperationOptions
        $options.SetCustomOption('PolicyPlatformContext_PrincipalContext_Type', 'PolicyPlatform_UserContext', $false)
        $options.SetCustomOption('PolicyPlatformContext_PrincipalContext_Id', $SidValue, $false)
        
        
        $namespace = 'root\cimv2\mdm\dmmap'
        $className = 'MDM_VPNv2_01'
        
        try{
            $session = New-CimSession
            $deleteInstances = $session.EnumerateInstances($namespace, $className, $options)
            foreach ($deleteInstance in $deleteInstances){
                 $InstanceId = $deleteInstance.InstanceID
                 if($InstanceId -eq $ProfileNameEscaped){
                     $session.DeleteInstance($namespace, $deleteInstance, $options)
                    Write-Verbose "Removed $ProfileName profile $InstanceId"
                 } else {
                    Write-Verbose "Ignoring existing VPN profile $InstanceId"
                 }
             }
         }
         catch{
            Throw
         }
    
         try{
            $newInstance = New-ObjectMicrosoft.Management.Infrastructure.CimInstance './Vendor/MSFT/VPNv2', $namespace
            $property = [Microsoft.Management.Infrastructure.CimProperty]::Create('ParentID', $nodeCSPURI, 'String', 'Key')
            $newInstance.CimInstanceProperties.Add($property)
            $property = [Microsoft.Management.Infrastructure.CimProperty]::Create('InstanceID', $ProfileNameEscaped, 'String', 'Key')
            $newInstance.CimInstanceProperties.Add($property)
            $property = [Microsoft.Management.Infrastructure.CimProperty]::Create('ProfileXML', $ProfileXML, 'String', 'Property')
            $newInstance.CimInstanceProperties.Add($property)
            $session.CreateInstance($namespace, $newInstance, $options)
             
            Write-Verbose 'Created $ProfileName profile.'
        }
        catch{
            Throw
        }
    
        $Script | Out-File -FilePath ($env:USERPROFILE + '\desktop\VPN_Profile.ps1')
        Write-Verbose 'Successfully created VPN_Profile.xml and VPN_Profile.ps1 on the desktop.'
    }
    
    New-VMProfile -Verbose


    \_(ツ)_/

    Tuesday, January 29, 2019 4:20 PM
  • I think that article was copied from an old kb or library article without any checking of the code. Microsoft has been migrating documentation to their new docs platform. We can provide feedback, but it requires a GitHub account.

    Richard Mueller - MVP Enterprise Mobility (Identity and Access)


    Tuesday, January 29, 2019 4:24 PM
  • By using the XML type we can let the type automatically encode the strings we are adding:

    [xml]$ProfileXML = @'
        <VPNProfile>
           <DnsSuffix>{0}</DnsSuffix>
           <NativeProfile>
                <Servers>{1}</Servers>
                <NativeProtocolType>IKEv2</NativeProtocolType>
                <Authentication>
                    <UserMethod>Eap</UserMethod>
                    <Eap>
                        <Configuration>{2}</Configuration>
                    </Eap>
                </Authentication>
                <RoutingPolicyType>SplitTunnel</RoutingPolicyType>
            </NativeProfile>
            <AlwaysOn>true</AlwaysOn>
            <RememberCredentials>true</RememberCredentials>
            <TrustedNetworkDetection>{3}</TrustedNetworkDetection>
            <DomainNameInformation>
                <DomainName>{4}</DomainName>
                <DnsServers>{5}</DnsServers>
            </DomainNameInformation>
        </VPNProfile>
    '@ -f $DnsSuffix, $Servers, $EAPSettings, $TrustedNetwork, $DomainName, $DNSServers
    
        $ProfileXML.Save("$env:USERPROFILE\desktop\VPN_Profile.xml")

    This eliminates all of the bad conversion lines.

    We can encode individual strings with this:

    [System.Xml.XmlConvert]::EncodeName($name)

    But loading as XML will do that for us.

    function New-VMProfile{
        [CmdletBinding()]
        $TemplateName = 'Template'
        $profileName = [System.Xml.XmlConvert]::EncodeName('Contoso AlwaysOn VPN')
        $Servers = 'vpn.contoso.com'
        $DnsSuffix = 'corp.contoso.com'
        $DomainName = '.corp.contoso.com'
        $DNSServers = '10.10.0.2,10.10.0.3'
        $TrustedNetwork = 'corp.contoso.com'
        
        Try{
            $Connection = Get-VpnConnection -Name $TemplateName -ErrorAction Stop
        }
        Catch{
            Throw
            return
        }
        
        $EAPSettings = $Connection.EapConfigXmlStream.InnerXml
    
    [xml]$profileXML = @'
        <VPNProfile>
           <DnsSuffix>{0}</DnsSuffix>
           <NativeProfile>
                <Servers>{1}</Servers>
                <NativeProtocolType>IKEv2</NativeProtocolType>
                <Authentication>
                    <UserMethod>Eap</UserMethod>
                    <Eap>
                        <Configuration>{2}</Configuration>
                    </Eap>
                </Authentication>
                <RoutingPolicyType>SplitTunnel</RoutingPolicyType>
            </NativeProfile>
            <AlwaysOn>true</AlwaysOn>
            <RememberCredentials>true</RememberCredentials>
            <TrustedNetworkDetection>{3}</TrustedNetworkDetection>
            <DomainNameInformation>
                <DomainName>{4}</DomainName>
                <DnsServers>{5}</DnsServers>
            </DomainNameInformation>
        </VPNProfile>
    '@ -f $DnsSuffix, $Servers, $EAPSettings, $TrustedNetwork, $DomainName, $DNSServers
    
        $profileXML.Save("$env:USERPROFILE\desktop\VPN_Profile.xml")
        
        Try{
            $user = [System.Security.Principal.NTAccount]::New("$env:USERDOMAIN\$env:USERNAME")
            $sid = $user.Translate([System.Security.Principal.SecurityIdentifier])
            $SidValue = $sid.Value
            Write-Verbose "User SID is $SidValue."
        }
        Catch{
            Throw
            return
        }
    
        $options = New-Object Microsoft.Management.Infrastructure.Options.CimOperationOptions
        $options.SetCustomOption('PolicyPlatformContext_PrincipalContext_Type', 'PolicyPlatform_UserContext', $false)
        $options.SetCustomOption('PolicyPlatformContext_PrincipalContext_Id', $SidValue, $false)
        
        
        $namespace = 'root\cimv2\mdm\dmmap'
        $className = 'MDM_VPNv2_01'
        
        try{
            $session = New-CimSession
            $instances = $session.EnumerateInstances($namespace, $className, $options)
            foreach ($instance in $instances){
                 $InstanceId = $instance.InstanceID
                 if($InstanceId -eq $profileName){
                     $session.DeleteInstance($namespace, $instance, $options)
                    Write-Verbose "Removed $profileName profile $InstanceId"
                 } else {
                    Write-Verbose "Ignoring existing VPN profile $InstanceId"
                 }
             }
         }
         catch{
            Throw
         }
    
         try{
            
            $newInstance = New-ObjectMicrosoft.Management.Infrastructure.CimInstance './Vendor/MSFT/VPNv2', $namespace
            $property = [Microsoft.Management.Infrastructure.CimProperty]::Create('ParentID', $nodeCSPURI, 'String', 'Key')
            $newInstance.CimInstanceProperties.Add($property)
            $property = [Microsoft.Management.Infrastructure.CimProperty]::Create('InstanceID', $profileName, 'String', 'Key')
            $newInstance.CimInstanceProperties.Add($property)
            $property = [Microsoft.Management.Infrastructure.CimProperty]::Create('ProfileXML', $profileXML, 'String', 'Property')
            $newInstance.CimInstanceProperties.Add($property)
            $session.CreateInstance($namespace, $newInstance, $options)
             
            Write-Verbose 'Created $ProfileName profile.'
        }
        catch{
            Throw
        }
    
        $Script | Out-File -FilePath ($env:USERPROFILE + '\desktop\VPN_Profile.ps1')
        Write-Verbose 'Successfully created VPN_Profile.xml and VPN_Profile.ps1 on the desktop.'
    }
    
    New-VMProfile -Verbose


    \_(ツ)_/

    Tuesday, January 29, 2019 4:48 PM