Change IIS Site Home Directory w/ Powershell - iis

I can query the AD and find all the IIS sites and their virtual directories, now I need to be able to update those home directories and save the changes.
After I fetch the directory entry I can display the site path using $site.Path, however setting it doesn't seem to have any effect. It never changes the actual stored path.
I have tried $site.Path = <new path> and $site.Put( "Path", <new path> ) but neither have these seem to be affecting the stored path.
$site = $iis.psbase.children |
where {$_.keyType -eq "iiswebserver"} |
where {$_.psbase.properties.servercomment -eq $siteConfig.name };
$s = [ADSI]($site.psbase.path + "/ROOT");
$s.Path
# $s.Path = $siteConfig.path
# $s.Put("Path", $siteConfig.path )
$s.psbase.CommitChanges()

Import-Module WebAdministration
Set-ItemProperty 'IIS:\Sites\Default Web Site\' -name physicalPath -value $siteConfig.path
http://technet.microsoft.com/en-us/library/ee909471(WS.10).aspx

Ok, I tried this and it seems to work:
$s.psbase.properties.path[0] = $siteConfig.path
$s.psbase.CommitChanges()
Is there a better cleaner way of handling this?

Related

WinSCP - How to download only folders/files 1 day old while excluding empty folders/files? [duplicate]

I am limited to PuTTY and WinSCP only.
I am trying to download log directories with log files. For example, I want to grab all log_files 6 days old or newer. log_dir2 and log_dir3 including the folders match the criteria, while log_dir1 and its files does not.
DIR/log_dir1/log_files % older than 6 days
DIR/log_dir2/log_files % meets criteria
DIR/log_dir3/log_files % meets criteria
My problem is that while the log_files of log_dir1 are not downloaded, the syntax I am currently using downloads the log_dir1 folder. Normally, not a big deal, but we are talking hundreds of log_dir folders (all empty as the files are older than 6 days). For reasons beyond my control, I cannot move or archive these old log directories with their log files.
My question is simply, how do I change my syntax to ignore folders that are older than 6 days as well as files.
get -filemask="*>6D" /DIR/* C:\temp
I have tried several different combinations of parameters and I have read the support page about Directory Masks and Path Masks. I cannot get any of them working (version issue?). Can anyone explain their syntax better than the help page. I will update tomorrow with the current version of WinSCP that I am using.
Time constraint in WinSCP file mask cannot be used for directories.
But you can prevent WinSCP from creating the empty folders. Use -rawtransfersettings switch with ExcludeEmptyDirectories setting.
get -rawtransfersettings ExcludeEmptyDirectories=1 -filemask="*>6D" /DIR/* C:\temp
This is the original answer, before WinSCP supported ExcludeEmptyDirectories. It might still be useful as a basis for implementations that have even more specific constraints.
You can implement this custom logic easily in PowerShell script with a use of WinSCP .NET assembly:
# Load WinSCP .NET assembly
Add-Type -Path "WinSCPnet.dll"
# Set up session options
$sessionOptions = New-Object WinSCP.SessionOptions -Property #{
Protocol = [WinSCP.Protocol]::Sftp
HostName = "example.com"
UserName = "username"
Password = "password"
SshHostKeyFingerprint = "..."
}
$remotePath = "/remote/path"
$localPath = "C:\local\path"
$limit = (Get-Date).AddDays(-6)
$session = New-Object WinSCP.Session
# Connect
$session.Open($sessionOptions)
# Enumerate files to download
$fileInfos =
$session.EnumerateRemoteFiles(
$remotePath, $Null, [WinSCP.EnumerationOptions]::AllDirectories) |
Where-Object { $_.LastWriteTime -gt $limit }
foreach ($fileInfo in $fileInfos)
{
$localFilePath =
[WinSCP.RemotePath]::TranslateRemotePathToLocal(
$fileInfo.FullName, $remotePath, $localPath)
# If the corresponding local folder does not exist yet, create it
$localFileDir = Split-Path -Parent $localFilePath
if (!(Test-Path -Path $localFileDir))
{
Write-Host "Creating local directory $localFileDir..."
New-Item $localFileDir -ItemType directory | Out-Null
}
Write-Host "Downloading file $($fileInfo.FullName)..."
# Download file
$sourcePath = [WinSCP.RemotePath]::EscapeFileMask($fileInfo.FullName)
$transferResult = $session.GetFiles($sourcePath, $localFilePath)
# Did the download succeeded?
if (!$transferResult.IsSuccess)
{
# Print error (but continue with other files)
Write-Host ("Error downloading file ${remoteFilePath}: " +
$transferResult.Failures[0].Message)
}
}
$session.Dispose()
Write-Host "Done."
Run the script (download.ps1) like:
powershell.exe -ExecutionPolicy Unrestricted -File download.ps1

unable to append data to sharepoint file via Azure Automation

Ok I have asked a question like this but now I am trying to perform the task via Azure Automation. I can connect to the SharePoint site via Azure Automation (powershell). with the correct credentials. I can download the file and append data to it. But I can when I try and upload the file back to SharePoint it adds the contents 3 times and then Azure Automation suspends the Runbook after 3 times.
It does run perfect if I upload this file as a different file name.
$siteurl="https://abc.sharepoint.com/sites/xxx/teamsites/os"
$credSP = Get-AutomationPSCredential -Name 'test'
$fileFolder = "$Env:temp"
Connect-PnPOnline -Url $siteurl -Credentials $credSP
Get-PnPFile -Url "/sites/xxx/teamsites/os/Directory and Operating
Systems/test.csv" -Path $fileFolder -Filename test.csv -AsFile -Force
$test = "31-07-2019 -11:35"
Add-Content -Path $fileFolder\test.csv $test
Add-PnPFile -Path $fileFolder\test.csv -Approve -Folder "Directory and
Operating Systems" #-ErrorAction Ignore
Here are the results
test test
31-07-2019 -11:35
31-07-2019 -11:35
31-07-2019 -11:35
As you can see it added $test 3 times. But I dont have this issue if I upload it as a new file name.
Ok after a while I have fix the issue.
After the add-pnpfile ...... you pipe it to | out-null
Thats it. the sript stops after it uploads ,
happy days

How to find out MACHINE/WEBROOT/APPHOST location of an application

I am currently writing a security auditing script for IIS 10 in Powershell. I have never even remotely worked with IIS before. I am supposed to run commands like this:
Get-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST/<website name>' -filter 'system.web/authentication/forms' -name 'protection'
Where can I find the website name ?
Thanks
As lex mentioned, we could use Get-Website or WebApplication to iterate all sites/applications.
If you just want to list the website name in the Powershell you could add below command.
Get-WebSite | Format-List -Property Name
Result example:

Using Powershell to create a web application in a folder that is not an application

I want to create a web application in IIS that does not live at the root of the IIS site.
i.e. MySite/beta/WebApplication.
This is my starting point:
New-WebApplication "WebApplication" -Site "MySite" -ApplicationPool "MyAppPool" -PhysicalPath "C:\Sites\MySite\beta\WebApplication"
That creates me the physical structure I want C:\Sites\MySite\beta\WebApplication , but makes IIS look like this:
MySite (IIS Web Site)
WebApplication (IIS WebApplication)
beta (Folder)
WebApplication (Folder)
Is there a way this can be done via powershell? I do not really want beta to be a web application, just a folder.
I know this post is a little older but here is a powershell script I wrote that converts an existing folder to a web application in IIS or if it doesn't exist creates a new folder and web app. It also creates the app pool for it as well. It receives an array of app names so you can create more than one web application. This was my first powershell script so if you have any suggestions feel free to comment.
#Receives an array of appnames and creates the app pools and web applications or converts the folder to an application
Param([parameter(Mandatory=$true)][string[]]$appNames)
$useDefaultPhysicalPath = Read-Host "Would you like to use the default physical path? (C:\inetpub\wwwroot\)";
Import-Module WebAdministration;
$physicalPath = "C:\inetpub\wwwroot\";
if(!($useDefaultPhysicalPath.ToString().ToLower() -eq "yes" -or $useDefaultPhysicalPath.ToString().ToLower() -eq "y"))
{
$physicalPath = Read-Host "Please enter the physical path you would like to use with a trailing \ (do not include the app name)";
}
$appPath = "IIS:\Sites\Default Web Site\";
foreach($appName in $appNames)
{
if((Test-Path IIS:\AppPools\$appName) -eq 0)
{
New-WebAppPool -Name $appName -Force;
}
if((Test-Path $appPath$appName) -eq 0 -and (Get-WebApplication -Name $appName) -eq $null)
{
New-Item -ItemType directory -Path $physicalPath$appName;
New-WebApplication -Name $appName -ApplicationPool $appName -Site "Default Web Site" -PhysicalPath $physicalPath$appName;
}
elseif((Get-WebApplication -Name $appName) -eq $null -and (Test-Path $appPath$appName) -eq $true)
{
ConvertTo-WebApplication -ApplicationPool $appName $appPath$appName;
}
else
{
echo "$appName already exists";
}
}
Since you are using the same physical file repository that is used by the "MySite" collection, it will create the "beta" folder. If you place this new web application in its own path (i.e., "C:\Sites\WebApps\WebApplication") you will get the desired results. The code below worked for me.
New-WebApplication "TestingViaPosh" -Site "Default Web Site" -ApplicationPool "DefaultAppPool" -
PhysicalPath "C:\Users\MyUserId\Documents\TestWebApp"
EDIT: To create a web application in a folder underneath the root of a website, you need to first create the folder in the site you desire (i.e., "C:\Sites\MySite\Beta"). Then the Powershell command will look like this:
New-WebApplication "TestingViaPosh" -Site "Default Web Site\Beta" -ApplicationPool "DefaultAppPool" -PhysicalPath "C:\Users\MyUserId\Documents\TestWebApp"
Since some people use the term folder and Virtual Directory, I thought it would be worth posting how you create a New Web Application inside a Folder / Virtual Directory. Which looks like this in IIS Manager.
You simply need to use the Path as the site name.
Import-Module WebAdministration
$SiteName = "Act.Web.API" # IIS Site Name
New-WebVirtualDirectory -Site $SiteName -Name APFW-api -PhysicalPath C:\inetpub\wwwroot
New-WebApplication -Name Act.Web.API -Site $SiteName\APFW-api -PhysicalPath "C:\Program Files (x86)\ACT\APFW-api" -ApplicationPool $SiteAppPool
$SiteName\APFW-api equals "Act.Web.API\APFW-api" at run time so the highlighted application is created.

Get dbname from multiple web.config files with powershell

I would like to issue a powershell command to return me the connection string (specifically I am looking for the db name value) for all the web sites on a web server...
So I would like to see something like
site1 dbname=Northwind
site2 dbname=Fitch
site3 dbname=DemoDB
I have tried using the IIS Powershell snap-in... I thought I was close with this:
PS C:\Windows\system32> Get-WebApplication | Get-WebConfiguration -filter /connectionStrings/*
but... after looking at the results... my answer doesn't appear to be in there
I am very new to powershell - so excuse my ignornance and inexperience
Any help appreciated!
thanks!
Hopefully, this will get you started. This just assumes there will be a web.config file at the physical path of the web application's physical path. It does not recurse to find other web.config files in the web application. It also assumes your connection strings are in the connectionStrings configuration element.
Import-Module WebAdministration
Get-WebApplication | `
ForEach-Object {
$webConfigFile = [xml](Get-Content "$($_.PhysicalPath)\Web.config")
Write-Host "Web Application: $($_.path)"
foreach($connString in $webConfigFile.configuration.connectionStrings.add)
{
Write-Host "Connection String $($connString.name): $($connString.connectionString)"
$dbRegex = "((Initial\sCatalog)|((Database)))\s*=(?<ic>[a-z\s0-9]+?);"
$found = $connString.connectionString -match $dbRegex
if ($found)
{
Write-Host "Database: $($Matches["ic"])"
}
}
Write-Host " "
}
This post may give you an idea to start with. Basically load in the web.config file as an XML file and then just find the node where the connection string is.
Do something like $myFile = ([xml] Get-Content web.config). You can then pipe that to Get-Member ( $myFile | Get-Member -MemberType Property) to start working your way into the file to see what node has it. I'm not at a computer where I can show you some screenshots to explain it more, but you can check this chapter out from PowerShell.com "Master PowerShell" e-book that explains working with XML very well.

Resources