0

I updated my script and solved my previous issues about my second conditional did not triggered when i called my function. But now i found new problems: 1. when how do i put user input outside the function without changing my function template " function createIISWebsite($siteName,$sitePath,$siteUrl) "so, the function will be run when automatically without me manually calling it.

 function createIISWebsite($siteName,$sitePath,$siteUrl) {

    #Asking for User input
    $siteName = Read-Host "siteName: "
    $sitePath = Read-Host "sitePath: "
    $siteUrl = Read-Host "siteUrl: "
    
    try {
        
        # Check if site name already exists and update site path
        if ((Get-Website $siteName) -and (Test-Path $sitePath) )

            { Set-Location $sitePath  
              Write-Host "$siteName " -ForegroundColor Red -NoNewline; 
              Write-Host "already exist, updated the site path to "-NoNewline; 
              Write-Host "$sitePath "-ForegroundColor Yellow -NoNewline;  
              Write-Host "and you can access it via "-NoNewline;
              Write-Host "$siteUrl"-ForegroundColor Green -NoNewline;}
              
        # if not exists create new website * can specify port and protocol "http or https"
        # using out-null for cleaner output
        else 
            { $sitePort = Read-Host "Input Port: "
              $siteProtocolType = Read-Host "Input Protocol Type http or https: "
              New-Website -Name $siteName  -HostHeader $siteUrl -PhysicalPath $sitePath | Out-Null
              New-WebBinding -Name $siteName -Port $sitePort -Protocol $siteProtocolType
              Write-Host $siteName "successfully created, you can access it via" $siteUrl -ForegroundColor Green }
        }
    catch
            {Write-host "Error: $($_.Exception.Message)"}
            
return

}  
bob mar
  • 7
  • 3

1 Answers1

0

To test if a sitename already exists, use Get-IISSite.
Because you are asking for user input inside the function, there is no need for any of the function parameters.
return at the end of the function is also not needed.

Try:

function createIISWebsite {

    #Asking for User input
    $siteName = Read-Host "siteName: "
    $sitePath = Read-Host "sitePath: "
    $siteUrl  = Read-Host "siteUrl: "
    
    $existingSite = Get-IISSite -Name $siteName -ErrorAction SilentlyContinue
    # check If the site name already exists, update the existing using new input parameter
    if ($existingSite) {
        Write-Host "$siteName already exist, updated the site path to $sitePath and you can access it via $siteUrl"
    }
    #if not exist create new website using port 80 and shows successfully created new site
    else { 
        try {
            $null = New-Website -Name $siteName -Port 80 -HostHeader $siteUrl -PhysicalPath $sitePath -ErrorAction Stop
            Write-Host "$siteName successfully created, you can access it via $siteUrl"
        }
        catch {
            Write-host "Error: $($_.Exception.Message)"
        }
    }
}

If you do want to use parameters, then just do the Read-Host lines outside of the function like

function createIISWebsite {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true, Position = 0)]
        [string]$siteName,

        [Parameter(Mandatory = $true, Position = 1)]
        [string]$sitePath,

        [Parameter(Mandatory = $true, Position = 2)]
        [string]$siteUrl
    )
    $existingSite = Get-IISSite -Name $siteName -ErrorAction SilentlyContinue
    # check If the site name already exists, update the existing using new input parameter
    if ($existingSite) {
        try {
            # update the site physical path to whatever is in variable $sitePath
            # I don't know your configuration, but the path for Set-ItemProperty in IIS usually starts with "IIS:\Sites\"
            Set-ItemProperty "IIS:\Sites\$siteName" -Name physicalPath -Value $sitePath -ErrorAction Stop
            Write-Host "$siteName already exist, updated the site path to $sitePath and you can access it via $siteUrl"
        }
        catch {
            Write-Host "Error updating the site's physical path:`r`n$($_.Exception.Message)" -ForegroundColor Red
        }
    }
    # if not exist create new website using port 80 and shows successfully created new site
    else { 
        try {
            $null = New-Website -Name $siteName -Port 80 -HostHeader $siteUrl -PhysicalPath $sitePath -ErrorAction Stop
            Write-Host "$siteName successfully created, you can access it via $siteUrl"
        }
        catch {
            Write-Host "Error creating new website:`r`n$($_.Exception.Message)"
        }
    }
}

#Asking for User input
$siteName = Read-Host "siteName: "
$sitePath = Read-Host "sitePath: "
$siteUrl  = Read-Host "siteUrl: "

# now call the function with parameters NAMED
createIISWebsite -siteName $siteName -sitePath $sitePath -siteUrl $siteUrl

# or without the parameter names, just by position:
# createIISWebsite $siteName $sitePath $siteUrl
Theo
  • 57,719
  • 8
  • 24
  • 41
  • actually , i found the solution which is similar to your solution but now as per you said about function parameters actually it need to be done using parameters but i don't know how to implement input outside the function without messing it up and also `return` is needed too not sure why. Do you have solution regarding this – bob mar Mar 30 '22 at 14:21
  • @bobmar I have added an example how to use the function with parameters. As said, a single command `return` as the last line of a function is unneeded. When a function is done, it will return automatically to the calling script. Especially here, since the function does not actually return anything. – Theo Mar 30 '22 at 14:41
  • but can i do it without putting mandatory since it changed the template and position? and also `return` and also i changed my code in the question above way different than the one you put will it be effected ? – bob mar Mar 30 '22 at 14:52
  • @bobmar If you leave out `Mandatory`, chances are you do not get a value sent through as parameter. You can change leave out the `Position`'s of course, but then you either need to always check if you are sending the parameters in the expected order or always use them as Named parameters. – Theo Mar 30 '22 at 15:11
  • alright it is working fine now without mandatory and position but i cant make `set-location` works. the current path of website still using old one when i tried to change it to new path. it was working few hours ago not sure what i did wrong – bob mar Mar 30 '22 at 16:08
  • @bobmar I guess it all depends on what you give as value for parameter `sitePath`. The function does not set a new path for an existing siteName; it only writes information to the console. If you want to **update** the physical path for a site in IIS, you need to do what is in [here](https://stackoverflow.com/a/59081204/9898643). `Set-Location` only sets the **current working location** of PowerShell to a specified location` – Theo Mar 30 '22 at 16:45
  • but when i check on IIS Manager it was changed to specify location now it doesnt work anymore. and for the link u gave it doesnt work for me because my sitepath is not on IIS:\Sites\sitea i tried to change it to $sitePath still doesnt work – bob mar Mar 30 '22 at 17:06
  • @bobmar You have combined the test if the site name exists with a test to see if the given site path exist. What you want is first test if the site **Name** exists and inside that set the physical path to whatever is set in parameter `$sitePath`. Again, `Set-Location` does not set the path for the site, you need `Set-ItemProperty "IIS:\Sites\$siteName" -Name physicalPath -value $sitePath` to actually set the physical path for the site with that name. – Theo Mar 30 '22 at 17:13
  • @bobmar Please see my edited 2nd code. After changing the path open iis manager and refresh the site – Theo Mar 30 '22 at 17:32