Why Powershell's New-WebBinding commandlet creates incorrect HostHeader? - iis

I am trying to add an MSMQ binding for my IIS Web Site, correct binding should look like this:
So I am executing following line in PowerShell:
New-WebBinding -Name "My Site" -Protocol net.msmq -HostHeader "localhost"
and it creates the following binding:
prefixing it with *:80:, so my MSMQ messages don't get picked up by WCF service. Maybe I am doing it wrong? How to create a binding with Binding Information set to just "localhost" using this PowerShell comandlet?
Commandlet codumentaiton can be found here.

Looking at the decompiled code of the cmdlet, looks like it adding the IPAddress and Port information in the binding and there is no workaround to it.
Relevant sections from the code:
private string ipAddress = "*";
...
builder.Append(this.ipAddress);
...
builder.Append(":" + this.sitePort.ToString(CultureInfo.InvariantCulture) + ":");
But you can do what the cmdlet actually does ( below code from cmdlet):
new-itemproperty -path "IIS:\sites\test" -name bindings -value #{protocol="net.msmq"; bindingInformation="localhost"}

Give this a try:
New-ItemProperty "IIS:\sites\NameOfYourSite" -name bindings -value #{protocol="net.msmq";bindingInformation="localhost"}

If your are running PowerShell (Core), a.k.a PowerShell >v7.1.x, you will find yourself in trouble because...
WARNING: Module WebAdministration is loaded in Windows PowerShell using WinPSCompatSession remoting session;
please note that all input and output of commands from this module will be deserialized objects.
If you want to load this module into PowerShell please use 'Import-Module -SkipEditionCheck' syntax.
The IIS provider isn't available via remoting session.
The easiest trick is to redirect string via pipeline to Windows PowerShell.
"Import-Module WebAdministration;New-ItemProperty -Path `"IIS:\Sites\$($configuration.Website.Name)`" -Name Bindings -value #{protocol = `"net.msmq`"; bindingInformation = `"localhost`" }" | PowerShell
In this example, the website name is read from the configuration JSON. You can replace it by a hard-coded site name.

Related

Azure Automation Hybrid-Worker Get-AutomationPSCredential for PowerShell 7

We are moving a few Azure Automation Hybrid-worker scripts to PowerShell 7.1. In doing so one of the commands that work in PowerShell 5.1 is: [PSCredential] $AutomationCredential = Get-AutomationPSCredential -Name 'abcdef'. When we try the same command in PowerShell 7.1 we get an error The 'Get-AutomationPSCredential' command was found in the module 'Orchestrator.AssetManagement.Cmdlets', but the module could not be loaded. For more information, run 'Import-Module Orchestrator.AssetManagement.Cmdlets'
We have added the Import-Module to the code but we get Could not load file or assembly 'JobRuntimeData.Client, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.
We do find Orchestrator.AssetManagement.Cmdlets the on the hybrid-worker, in the sandbox area. We know that this module is loaded when the hybrid-worker is installed (https://learn.microsoft.com/en-us/azure/automation/shared-resources/modules#internal-cmdlets).
Based on the Microsoft official document
The 'Get-AutomationPSCredential is currently supported till Azure powershell 6.6.0
NOTE: Powershell 7.1 is still in preview so this may be the reason for the error .
Please refer this MS DOC for more information.
We are assuming the Orchestrator.AssetManagement.Cmdlets is bugged at this point, but have not found anything to say that it is. To get around it we were going to use a runbook variable to store the password, but it needs the cmdlet to actually decode a secret/hidden value.
In the end, we used a key vault to store the password. The following is what was used as a workaround.
$User = "AutomationUser"
$KeyVaultName = "KeyVault"
try {
$Password = (ConvertTo-SecureString (Get-AzKeyVaultSecret -VaultName $KeyVaultName -Name $User -AsPlainText) -AsPlainText -Force)
[PSCredential] $AutomationCredential = New-Object System.Management.Automation.PSCredential($User, $Password)
}
catch {
$ErrorMessage = "Unable to retrieve credentials for user: [${$User}]. $_"
throw $ErrorMessage
BREAK
}

How to create a Microsoft Team using a Queue Triggered Azure Function writed in PowerShell?

I want to create a Team by using an azure function triggered by an Azure Queue.
Unfortunetly when I run the code it is not working inside the Azure Function.
I'm wondering. Is there a way to create a Microsoft Team using PowerShell inside an Azure Function ?
Import-module MicrosoftTeams
$group = New-Team -MailNickname "teamTitle" -displayname "teamTitle" -Visibility "private"
Add-TeamUser -GroupId $group.GroupId -User "user#etc.com"
New-TeamChannel -GroupId $group.GroupId -DisplayName "General"
Working locally. Not working within the Azure Function.
Bellow the error i'm getting :
ERROR: Import-Module : The specified module 'MicrosoftTeams' was not loaded because no valid
module file was found in any module directory. At D:\home\site\wwwroot\CreateTeam\run.ps1:3
char:1 + Import-Module MicrosoftTeams + [...]
Thank you
Based on the error message, your Function app does not have the MicrosoftTeams module installed. You need to include a reference to this module to the requirements.psd1 file (see https://learn.microsoft.com/azure/azure-functions/functions-reference-powershell#dependency-management for more details).
Currently this module is not yet natively integrated into the azure functions under powershell
To see all the available packages go in App Service -> Advanced Tools -> DebugConsole -> Powershell and run :
Write-Output ‘Getting PowerShell Module’
$result = Get-Module -ListAvailable |
Select-Object Name, Version, ModuleBase |
Sort-Object -Property Name |
Format-Table -wrap |
Out-String
Write-output `n$result
To manually add a package, It is necessary to create a directory "Module" At the same level as the directory of the function, They will be automatically preloaded.
(https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-powershell step "Function app-level Modules folder")
After installation of the module. use below code in your script to automate the process.
$securedpassword = ConvertTo-SecureString $Password -AsPlainText -Force
$mycredentials = New-Object System.Management.Automation.PSCredential ($Username, $securedpassword )
$res = Connect-MicrosoftTeams -Credential $mycredentials

powershell : i cant open remote session without specify the FQDN anymore

Some days ago, i was able do create a remote session using short name of the remote server/workstation.
This doesnt work anymore error is :
+ CategoryInfo : InvalidArgument : (computername1:String) [Enter-PSSession], PSRemotingTransportExcepti
+ FullyQualifiedErrorId : CreateRemoteRunspaceFailed
but when i use the complete domain name it is working :
nsn computername1.domain.com
Dns resolution is correct, what else can i check to troubleshoot this problem ?
I've finaly found it ! :)
I had to modify the default pssession option and set the proxy to 'NoProxyServer' instead of the default value 'none'
so I added this line in my profile :
$PSSessionOption = New-PSSessionOption -ProxyAccessType NoProxyServer
From technet :
None The proxy access type is not specified. This means that proxy
information, such as the access type, authentication mechanism, and
credential, is not passed to the Web Services for Management (WSMan)
protocol service. This field is introduced in Windows PowerShell 2.0.
NoProxyServer No proxy server is used when configuring proxy settings.
This mechanism resolves all the host names locally. This field is
introduced in Windows PowerShell 2.0.
As i cant find the source of the problem here is my workaround :
rename the two aliases nsn and etsn and replace them by these functions in my profile :
rename-item alias:\nsn nsn2 -ea silentlycontinue
rename-item alias:\etsn etsn2 -ea silentlycontinue
function resolve-hostname{
param($computername)
[System.Net.Dns]::GetHostEntry($computername) |select -ExpandProperty hostname
}
function nsn{
param($computername)
$cn=resolve-hostname $computername
new-pssession -cn $cn
}
function etsn{
param($computername)
$cn=resolve-hostname $computername
enter-pssession -cn $cn
}

"Failed to enumerate SSL bindings" error code 234

Does anybody know how to resolve this issue?
Replicate when you type the following command in PowerShell.
dir iis:\sslbindings
I have comes across this page on Microsoft TechNet which doesn't address the problem.
Edit
When invoking the command I get the error
failed to enumerate SSL bindings
Apparently due to a corrupted registry?
In my case, I've got the error when I had both SslCertStoreName and DefaultSslCtlStoreName in the registry. I deleted DefaultSslCtlStoreName and the error is gone for a while. For some reason, DefaultSslCtlStoreName was created in the registry again, and I've got the error again. So I wrote a simple powershell script that deletes it.
This is the part from my build script.
function CleanupSslBindings()
{
$sslBindingsPath = 'hklm:\SYSTEM\CurrentControlSet\services\HTTP\Parameters\SslBindingInfo\'
$registryItems = Get-ChildItem -Path $sslBindingsPath |
Where-Object -FilterScript { ($_.Property -eq 'DefaultSslCtlStoreName')}
If ($registryItems.Count -gt 0) {
ForEach ($item in $registryItems) {
$item | Remove-ItemProperty -Name DefaultSslCtlStoreName
Write-Host "Deleted DefaultSslCtlStoreName in " $item.Name
}
} Else {
Write-Host "No DefaultSslCtlStoreName found. The SSL Bindings registry is clean."
}
}
In my case, I had built WCF services hosted as windows services. When I did this, I apparently didn't know (and still don't) how to assign things like appid's (noticeable when you netsh http show sslcert), and other items that crop up... including an item related to this error.
Essentially, I read the same page the OP did: https://social.technet.microsoft.com/Forums/windowsserver/en-US/87b1252d-a6a0-4251-bbb6-38e104a8c07a/enumerating-iissslbindings-gives-failure-on-one-machine-works-on-another?forum=winserverpowershell
...and using a regedit, went to the key: HKLM\System\Currentcontrolset\services\http\parameters\sslbindinginfo
I saw all the same entries I see when I do the netsh command above. However, my wcf services are listed first, followed by my IIS sites. None of my wcf services had the SSLCertStoreName key (only the IIS sites had the key). Following the article's explanation that the first entry needs to have that registry key (this is a bug in my opinion), I performed the following PowerShell commands:
Try
{
Get-ChildItem IIS:\SslBindings
}
Catch
{
$1stentry = Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\services\HTTP\Parameters\SslBindingInfo | Select-Object -First 1
$1stentry | New-ItemProperty -Name "SslCertStoreName" -Value "MY"
Get-ChildItem IIS:\SslBindings
}
This code works for me. And that article helped get me here and understand that my root cause of this 234 error code, is an assumed self-inflicted wound by not installing my WCF services correctly. YMMV. Hope this helps.
Apologies for the delay but I resolved the issue with the following script (see below). For some bizarre reason (I don't know why) something was adding two entries in my registry and after removing these the problem went away. I figured this out as I compared my registry to another machine who wasn't having this problem and found the culprit.
Remove-ItemProperty -Path "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP\Parameters\SslBindingInfo\" -Name "[::1]:26143" -ErrorAction SilentlyContinue
Remove-ItemProperty -Path "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP\Parameters\SslBindingInfo" -Name "127.0.0.1:26143" -ErrorAction SilentlyContinue
echo "Done."
#Bewc I reckon you are onto something there although I think it affects more than just WCF services. We have a powershell script that builds and deploys a website onto a machine (sounds crazy I know). Who or what creates these entries I have no idea but perhaps some background process in IIS?

Powershell command to set IIS logging settings

I'm creating a powershell script so I can create website hosting with a single command using the IIS Powershell Management Console.
I have the commands I need to create the IIS Site and add bindings for the domain names etc...
The one piece of the puzzle I'm missing though is how to change the default Logging directory from %SystemDrive%\inetpub\logs\LogFiles to my own folder that's not on the boot drive of the server.
After extensive searching I expected to find a command along the lines of the following pseudo powershell
New-ItemProperty IIS:\Sites\MyNewSite -name logging -value #{format='W3C';directory='d:\sites\site\logs';encoding=UTF-8}
Please could you show me with an example how you change the logging folder in the IIS Powershell Management Console
Thanks in advance
Import-Module WebAdministration
Set-WebConfigurationProperty "/system.applicationHost/sites/siteDefaults" -name logfile.directory -value $logdir
While testing the answer from this thread, toggling options via IIS Manager and PowerShell, I stumbled on something that has been hidden to me. In IIS Manager, choosing Configuration Editor and making a change, allows the IIS Manager to generate and display the script for the change in C#, JavaScript, AppCmd.exe and PowerShell. Just click the Generate Script option.
[]
For changing an individual web site's logFile configuration, the original post was nearly correct. Instead of New-ItemProperty, use Set-ItemProperty, like so...
Set-ItemProperty "IIS:\Sites\$SiteName" -name logFile -value #{directory=$LogPath}
For changing the server-wide default settings, see Andy Schneider's answer.
For more information about the options available, see this IIS.net article.
This works as well, using the WebAdministration Module
Import-Module WebAdministration
$site = gi IIS:\Sites\MyNewSite
$site.Logging.format='W3C'
$site.Logging.directory='d:\sites\site\logs'
$site.Logging.encoding=UTF-8
$site | set-item
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Web.Administration")
$iis = new-object Microsoft.Web.Administration.ServerManager
$web = $iis.Sites["test"]
#set new logpath, must be existing
$web.LogFile.Directory = "F:\Logfiles\"
$iis.CommitChanges()
If you host multiple sites on a single server and want them to all log to the same log file, the process is quite different. It took some digging to find clues here and here, so I thought I would leave a description behind for anyone else with this need.
The following two statements will combine logs for all of your websites into a folder e:\log\w3svc.
Set-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST' -filter 'system.applicationHost/log' -name CentralLogFileMode -Value 'CentralW3C'
Set-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST' -filter 'system.applicationHost/log' -name centralW3CLogFile.directory -value 'e:\log'

Resources