Disable UAC, restart and install programs - powershell-workflow

I tried to disable UAC, restart the machine and install the program. I found an article how can create workflow, but it not works for me. When I run it once, the computer restarts, UAC is still enabled, and nothing happen.
workflow Resume_Workflow
{
Set-ItemProperty -Path REGISTRY::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -Name ConsentPromptBehaviorAdmin -Value 0
Restart-Computer -Wait
Start-Process msiexec.exe -Verb runAs -PassThru -Wait -ArgumentList '/I C:\tmp\_deployment\tightvnc-2.8.11-gpl-setup-64bit.msi /quiet /norestart'
}
# Create the scheduled job properties
$options = New-ScheduledJobOption -RunElevated
$AtStartup = New-JobTrigger -AtStartup
# Register the scheduled job
Register-ScheduledJob -Name Resume_Workflow_Job -Trigger $AtStartup -ScriptBlock ({[System.Management.Automation.Remoting.PSSessionConfigurationData]::IsServerManager = $true; Import-Module PSWorkflow; Resume-Job -Name new_resume_workflow_job -Wait}) -ScheduledJobOption $options
# Execute the workflow as a new job
Resume_Workflow -AsJob -JobName new_resume_workflow_job
Any idea what's missing?
Thanks for the help.

Related

Publish ASP.Net site on Docker using MsDeploy

We are using MsDeploy for deploying our site on IIS. When we publish we get three files, viz.
MySite.deploy.cmd,
MySite.SetParameters.xml
MySite.zip.
And we run a command like;
MySite.cmd /Y /M:https://IpOfMachine/MsDeploy.axd
to deploy on the server.
Now we want to move it to docker, with docker file something like this -
FROM microsoft/iis
RUN powershell -NoProfile -Command Remove-Item -Recurse
C:\inetpub\wwwroot*
WORKDIR C:/DeploymentFiles
COPY DeploymentPackage/ .
RUN cmd MySite.cmd /Y /M:https://IpOfDockerInstance/MsDeploy.axd
But the MsDeploy thing is not working and giving 404 error. I think I need to add WebDepoly to get this working, but how to do it in Docker?
Any suggestions, please. I am a novice to Docker
It could be difficult to get started with docker, if one's is not through well with the basics. I spent some time in reading out more on it and finally come up with the following Docker file that worked for me. I have tired to document the script inline with a couple of references that helped me.
FROM microsoft/iis
#Keep the artifacts related for image in the same folder from where docker is running
RUN cmd mkdir C:/DeploymentFiles
WORKDIR C:/DeploymentFiles
# Copy and install msdeploy service
COPY WebDeploy_amd64_en-US.msi .
RUN msiexec /i WebDeploy_amd64_en-US.msi AGREETOLICENSE=yes ADDLOCAL=ALL /qn
RUN powershell Start-service MsDepSvc;
#Remove default iis site's contents
RUN powershell -NoProfile -Command Remove-Item -Recurse C:\inetpub\wwwroot\*
# Resolving 403 issue. Ref - https://github.com/microsoft/iis-docker/issues/5
#Adding a user so i can connect trough IIS Manager
RUN NET USER testing "Password01!" /ADD
RUN NET LOCALGROUP "Administrators" "testing" /add
#Grant Permissions
RUN icacls "C:\inetpub\wwwroot\*" /grant everyone:(OI)(CI)F /T
#Install neccassary features
RUN powershell Install-WindowsFeature Web-Mgmt-Service
RUN powershell Install-WindowsFeature Web-Windows-Auth
RUN powershell Install-WindowsFeature NET-Framework-45-ASPNET
RUN powershell Install-WindowsFeature Web-Asp-Net45
RUN powershell Install-WindowsFeature NET-WCF-HTTP-Activation45
#Start Service and make it autorun
RUN net start wmsvc
RUN sc config WMSVC start= auto
RUN powershell -NoProfile -Command \
Set-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\WebManagement\Server -Name EnableRemoteManagement -Value 1
# Copy deployment packages and related files to container to "C:/DeploymentFiles"
COPY DeployPackage/ .
# The Deploy_App.bat file contains the command to deploy using msdeploy
COPY Deploy_App.bat .
RUN C:/DeploymentFiles/Deploy_App.bat
# Resolve the ACL issues during deployment. Ref - https://fluentbytes.com/how-to-fix-error-this-access-control-list-is-not-in-canonical-form-and-therefore-cannot-be-modified-error-count-1/
COPY aclFix.ps1 .
RUN powershell.exe -executionpolicy bypass .\aclFix.ps1
RUN C:/DeploymentFiles/Deploy_App.bat
EXPOSE 80

IIS:\\AppPools appears to be empty when used from inside application pool

I am trying to run a PowerShell script to set some properties on an IIS application pool. The script works fine when I run it from the PowerShell application. However, it does not work when running from inside an IIS application pool.
The script looks as follows:
import-module webadministration
$WebSiteName = "MyWebsite"
$WebSiteFullName = "IIS:\Sites\" + $WebSiteName
$ApplicationPool = Get-Item $WebSiteFullName | Select-Object applicationPool
$ApplicationPoolFullName = "IIS:\AppPools\" + $ApplicationPool.applicationPool
Add-WebConfiguration -filter '/system.applicationHost/serviceAutoStartProviders' -value (#{name="ApplicationPreload";type="MyApplication.ApplicationPreload, MyApplication"})
set-itemproperty $WebSiteFullName -name applicationDefaults.serviceAutoStartEnabled -value True
set-itemproperty $WebSiteFullName -name applicationDefaults.serviceAutoStartProvider -value 'ApplicationPreload'
set-itemproperty $ApplicationPoolFullName -name autoStart -value True
set-itemproperty $ApplicationPoolFullName -name startMode -value 1 # 1 = AlwaysRunning
Its purpose is to make an ASP.NET application using Hangfire always running, as described here: http://docs.hangfire.io/en/latest/deployment-to-production/making-aspnet-app-always-running.html
The script runs fine when run in the PowerShell application.
However, when it from the ASP.NET application using System.Management.Automation, the last two lines fail. The error message is:
Cannot find path 'IIS:\\AppPools\\fwsetupsite' because it does not exist.
As a test, I added a line
dir IIS:\AppPools > c:\apppools.txt
which produces an empty file c:\apppools.txt if run from the ASP.NET application, but correctly dumps the names of all application pools into the file when run from the PowerShell application. So it seems that IIS:\\AppPools is empty.
The C# code which runs the script from within the ASP.NET application looks as follows:
using (PowerShell shell = PowerShell.Create())
{
string script = File.ReadAllText(FilePath);
shell.AddScript(script);
shell.Invoke();
}
It seems that making the modifications to the application pool in a background job solves the problem:
$job = Start-Job -ScriptBlock {
param($ApplicationPoolFullName)
import-module webadministration
# Enable auto start and always running on application pool
set-itemproperty $ApplicationPoolFullName -name autoStart -value True
set-itemproperty $ApplicationPoolFullName -name startMode -value 1 # 1 = AlwaysRunning, 0 = OnDemand
} -ArgumentList $ApplicationPoolFullName
Wait-Job $job | Out-Null
if ($job.State -eq 'Failed') {
exit 1
}
I am still curious about why it doesn't work when doing it directly in the main script, though.

Powershell scripting creation of a "sub" website

I have two folders:
c:\inetpub\site1
c:\inetpub\site1Sub
I want "site1" to be the "parent" website and "site1Sub" to be a "sub" website. Both sites should run under the same application pool, which is a custom pool created solely for these sites, call it "site1." In IIS Manager (7.5), I simply create the application pool, then the parent site, then right-click on the parent site and "Add Application," pointing it at the physical path "c:\inetpub\site1Sub." This all works fine.
When I try to script this in Powershell, however, things get difficult. I can create "site1" and the application pool with no problems. It's the sub-site that's being a pain. I've tried two approaches:
Approach 1: Use New-Item and set the app pool after.
$subSite = New-Item "IIS:\Sites\site1\site1Sub" -physicalPath "C:\inetpub\site1Sub" -type "Application"
$subSite | Set-ItemProperty -Name "applicationPool" -Value "site1"
With this approach, I receive an error after the Set-ItemProperty command:
Set-ItemProperty : Cannot find path 'C:\site1Sub' because it does not exist.
At line:1 char:127
+ $subSite | Set-ItemProperty -Name "applicationPool" -Value "site1" ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\site1Sub:String) [Set-ItemProperty], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.SetItemPropertyCommand
Approach 2: Create a virtual directory and use ConvertTo-WebApplication (as in this answer).
New-WebVirtualDirectory -Site "site1" -Name "site1Sub" -PhysicalPath "c:\inetpub\site1Sub"
ConvertTo-WebApplication -ApplicationPool "site1" "IIS:\Sites\site1\site1Sub"
This runs fine, and further, it looks fine in IIS Manager, but when I attempt to navigate to the site I receive an error stating that the web.config failed to parse:
It is an error to use a section registered as
allowDefinition='MachineToApplication' beyond application level. This
error can be caused by a virtual directory not being configured as an
application in IIS.
I'm totally stumped. How can I script this scenario in Powershell?
I've found that when creating an application under a website, I've needed to specify the -Force switch in the call to New-Item. I've left out the checking to see if the site already exists (Sneijder's answer shows how to do that with Test-Path), but this should do the trick:
Import-Module WebAdministration
$sitePath = 'IIS:\Sites\site1'
$subSitePath = "$sitePath\site1Sub"
$appPoolName = 'site1'
# Create Site and Subsite
New-Item $sitePath -PhysicalPath 'C:\Inetpub\site1' -Bindings #{protocol="http";bindingInformation=":80:"} }
New-Item $subSitePath -Type Application -PhysicalPath 'C:\Inetpub\site1Sub' -Force
# Create App Pool
New-Item "IIS:\AppPools\$appPoolName"
# Associate sites to App Pool
Set-ItemProperty $sitePath -Name applicationPool -Value $appPoolName
Set-ItemProperty $subSitePath -Name applicationPool -Value $appPoolName
As i understand you correctly, you would like to have following result in your local IIS Manager:
This script creates an application pool. Then it creates the root site and afterwards the subsite.
Import-Module WebAdministration
$iisAppPoolName = "applicationPool"
$iisAppPoolDotNetVersion = "v4.0"
$iisAppName = "site1"
$directoryPath = "C:\inetpub\site1"
$iisSubAppName = "site1sub"
$directorySubPath = "C:\inetpub\site1Sub"
#navigate to the app pools root
cd IIS:\AppPools\
#check if the app pool exists
if (!(Test-Path $iisAppPoolName -pathType container))
{
#create the app pool
$appPool = New-Item $iisAppPoolName
$appPool | Set-ItemProperty -Name "managedRuntimeVersion" -Value $iisAppPoolDotNetVersion
}
#navigate to the sites root
cd IIS:\Sites\
#check if the site exists
if (Test-Path $iisAppName -pathType container)
{
return
}
#create the site
$iisApp = New-Item $iisAppName -bindings #{protocol="http";bindingInformation=":80:"} -physicalPath $directoryPath
$iisApp | Set-ItemProperty -Name $iisAppPoolName -Value $iisAppPoolName
#create the subSite
$iisSubApp = New-WebApplication -Name $iisSubAppName -Site $iisAppName -PhysicalPath $directorySubPath -ApplicationPool $iisAppPoolName
Result:
Hope this helps.
Have you tried mapping your IIS directory tree as a PSDrive, then re-attempt approach 1?
https://technet.microsoft.com/en-us/library/ee176915.aspx
Do a Get-PSDrive to see what PS Providers are available to the host, then attempt to map it like a filesystem.
# For psprovider, I'm not sure if the provider name is 'IIS' or some other.
# For mapping remote drives, usually FileSystem works,
# but try Get-PSDrive to see whats available to your host for this switch.
New-PSDrive -name X -psprovider IIS -root 'IIS:\'
I don't have IIS config'd on my testbox to confirm for you, but just putting this up here to try.

cap deploy:cleanup fails with use_sudo=true

My capifony deployment works great, however the capifony cleanup command fails.
I'm using private keys over ssh, with sudo to gain write permissions on the deployment directories.
With extended logging the result of cap deploy:cleanup is this:
$ cap deploy:cleanup
* 2013-07-19 15:44:42 executing `deploy:cleanup'
* executing "sudo -p 'sudo password: ' ls -1dt /var/www/html/releases/* | tail -n +4 | sudo -p 'sudo password: ' xargs rm -rf"
Modifying permissions so that the deployment user has full write access to this directory is not an option in this instance.
Has anyone seen/worked around this issue? (This is on a RHEL6 server)
Yep, there is a problem with the cleanup command while using sudo at the moment. Here was my solution to fixing this. Add this to your deploy.rb
namespace :customtasks do
task :customcleanup, :except => {:no_release => true} do
count = fetch(:keep_releases, 5).to_i
run "ls -1dt #{releases_path}/* | tail -n +#{count + 1} | #{try_sudo} xargs rm -rf"
end
end
Then call that instead as cleanup
after "deploy:update", "customtasks:customcleanup"
More info at https://github.com/capistrano/capistrano/issues/474

How to check app pool last recycled

is it possible to check when i recycled the app pool last time, i want to check the date when my app pool was last recycled, is there anything in IIS i can get this info.
You could easily find the latest recycle time by using this powershell snippet:
(Get-Process -Id <ProcessId>).StartTime
Therefore find the process id of your web application in task manager.
First add the following columns via Tools > Select columns... : select PID and Command Line.
Look for any w3wp.exe process and find your application by examining the command-line (application pool name is part of it) and note down its PID.
Then run the powershell script to find the latest recycle time:
Hope this helps
If logging on recycles is turned on you can see this in the Event Viewer (System Log).
If it's not you can use PerfMon counters to see Process-Elapsed Time on the W3WP.exe representing your application pool (which will be the number of seconds since the last recycle)
To get all the information with one command use the Get-WmiObject instead of get-process.
Get-WmiObject Win32_Process -Filter "name = 'w3wp.exe'" | Select-Object Name, #{"name"="ApplicationPool";expression={(($_).CommandLine).split('"')[1] }},#{"name"="Starttime";expression={$_.ConvertToDateTime($_.CreationDate)}}
In Powershell:
(ps -id (Get-IISAppPool -Name <name>).WorkerProcesses.ProcessId).StartTime
If the pool has been recycled, then for some reason you may need to re-import the module to get the new processId:
$pool = Get-IISAppPool -Name <name>
$pool.recycle()
Import-Module -Force IISAdministration
(ps -id (Get-IISAppPool -Name <name>).WorkerProcesses.ProcessId).StartTime
This will give you a list of all the w3wp processes on the machine and their start times. The ErrorAction prevents the commandlet from throwing an error if no websites are started and therefore no w3wp processes exist
ps w3wp -ErrorAction SilentlyContinue | select ProcessName, StartTime
Tested on Server 2012 R2 with powershell v4.0
Get the worker process uptime(Recommended):
$poolName = <your pool name goes here eg. DefaultPool>
$poolProcess =(gwmi -NS 'root\WebAdministration' -class 'WorkerProcess' | select AppPoolName,ProcessId | Where-Object { $_.AppPoolName -eq $poolName } )
$lastStartTime=(Get-Process -Id $poolProcess.ProcessId).StartTime
write-output $lastStartTime
For it to work, make sure you have 'IIS management scripts and tools' enabled.
Second, way is using Event log, if enabled
Get-Eventlog -LogName system -Newest 1 -Source "WAS" -Message "*recycle of all worker processes in application pool '$poolName'*")
With Get-Eventlog you can use -After/-Before argument to further limit the result.
To check if Application pool is recycled in last 'X' minutes, following powershell snippet can be used:
function isRecycledInLastNMinutes($appPoolName, $lminutes){
$beforeDate = Get-Date -format 'u'
$afterDate = $beforeDate.addMinutes(-$lminutes)
$result = (Get-Eventlog -LogName system -Newest 1 -Source "WAS" -After $afterDate -Before $beforeDate -Message "*recycle of all worker processes in application pool '$appPoolName'*")
if( $result.length -eq 1){
return $true
}else{
retrun $false
}
}

Resources