Showing posts with label powershell. Show all posts
Showing posts with label powershell. Show all posts
Thursday, April 26, 2018
Project count and name length limitations of the Service Fabric tooling in Visual Studio
It would seem that I've just stumbled across the practical technical limit to how many services a Service Fabric application can have and still be debugged with Visual Studio: ~ 37. My problem would seem to be confirmed by this Github issue.
Friday, October 13, 2017
Resolving PowerShell cmdlets with conflicting names
I've recently run into the issue of needing to use multiple modules that happen to contain cmdlets that have the same name in each. According to this article, you can use module name qualified cmdlet calls to resolve naming conflicts.
Sunday, April 02, 2017
How to copy files to a remote machine with powershell 5 (the easy way)
> $creds = Get-Credential
> $session = New-PSSession -ComputerName "myremotemachine.mydomain.com" -UseSSL -Credential $creds
> Copy-Item -Path "C:\my\folder\somewhere" -Destination "C:\path\on\remote\machine" -ToSession $session
Done and done. This assumes that you have PowerShell set up for PSRemoting on the remote machine with a certificate. There's plenty of other tutorials for doing that.
> $session = New-PSSession -ComputerName "myremotemachine.mydomain.com" -UseSSL -Credential $creds
> Copy-Item -Path "C:\my\folder\somewhere" -Destination "C:\path\on\remote\machine" -ToSession $session
Done and done. This assumes that you have PowerShell set up for PSRemoting on the remote machine with a certificate. There's plenty of other tutorials for doing that.
Thursday, September 01, 2016
Unblocking zip files, the permanent solution
My team recently migrated their code to Visual Studio Online (aka VSO aka VSTS), which means that any time we do our builds, we now have to download our build output through the browser as a zip file rather than copying from a file share as we formerly did when our code was built on-premise. As a consequence of this, we now stumble across a feature of Windows: automatic file blocking.
Any time we download a zip from the internet, any scripts extracted from it are automatically blocked by Windows using metadata attached to the file in the NTFS file system. This means we have to manually unblock our scripts every time we download a build and want to deploy it (But Alex, why aren't you deploying your systems automatically through a deployment manager ? Our company isn't there yet, but we're getting there). That said, there's a way to disable this feature, detailed here:
http://winaero.com/blog/disable-downloaded-files-from-being-blocked-in-windows-10/
The short of it is that there exists a group policy for disabling tracking of zone information for files downloaded from the Internet.
Start -> Run -> gpedit.msc -> Local Computer Policy -> User Configuration -> Administrative Templates -> Windows Components -> Attachment Manager -> "Do not preserve zone information in file attachments" : Enabled.
Done.
Any time we download a zip from the internet, any scripts extracted from it are automatically blocked by Windows using metadata attached to the file in the NTFS file system. This means we have to manually unblock our scripts every time we download a build and want to deploy it (But Alex, why aren't you deploying your systems automatically through a deployment manager ? Our company isn't there yet, but we're getting there). That said, there's a way to disable this feature, detailed here:
http://winaero.com/blog/disable-downloaded-files-from-being-blocked-in-windows-10/
The short of it is that there exists a group policy for disabling tracking of zone information for files downloaded from the Internet.
Start -> Run -> gpedit.msc -> Local Computer Policy -> User Configuration -> Administrative Templates -> Windows Components -> Attachment Manager -> "Do not preserve zone information in file attachments" : Enabled.
Done.
Labels:
block,
blocked,
file,
gpedit.msc,
group policy,
information,
powershell,
ps1,
scripts,
unblock,
windows,
zip,
zone
Tuesday, August 23, 2016
Getting verbose output from an Invoke-Command -ScriptBlock in PowerShell
It's often very useful to invoke commands on other machines, e.g. in deployment scripts. It can be even more useful to have logging of what actually gets executed on those other machines, e.g.
$myJob = Invoke-Command -AsJob -ScriptBlock {
Param()
Do-Thing -Verbose
}
However, in this instance, you wouldn't get the output of the Do-Thing command because it's writing to the Verbose stream of a script block being executed on a separate machine. Now, it's not that PowerShell can't collect the output of that Verbose stream for you, it can. You just need to instruct it how. The difference:
$myJob = Invoke-Command -AsJob -Verbose -ScriptBlock {
[CmdletBinding()]
Param()
Do-Thing -Verbose
}
$myJob = Invoke-Command -AsJob -ScriptBlock {
Param()
Do-Thing -Verbose
}
However, in this instance, you wouldn't get the output of the Do-Thing command because it's writing to the Verbose stream of a script block being executed on a separate machine. Now, it's not that PowerShell can't collect the output of that Verbose stream for you, it can. You just need to instruct it how. The difference:
$myJob = Invoke-Command -AsJob -Verbose -ScriptBlock {
[CmdletBinding()]
Param()
Do-Thing -Verbose
}
Now you'll be able to collect the Verbose output of your script block. The difference is that you need to pass the Verbose flag to the script block, and make it a cmdlet by adding the [CmdletBinding()] attribute to your block.
Wednesday, August 03, 2016
WADK Deployment Tools on Windows Server 2008 giving error "The program can't start because api-ms-win-downlevel-advapi32-l4-1-0.dll is missing from your system"
Got this error at an extremely inconvenient time when trying to write some automation scripts for Windows Optional Features using the DISM module as part of the Windows Assessment and Deployment Kit running on Windows Server 2008 R2: "The program can't start because api-ms-win-downlevel-advapi32-l4-1-0.dll is missing from your system"
It turns out that the installer for this particular product isn't reliable when you uninstall and then reinstall the ADK. The problem turned out to be that the PATH variable hadn't been updated on the second install, so the PowerShell module that was invoking the DISM.exe executable wasn't able to find the required DLLs, even though they were in the same path as the executable. Go figure.
It turns out that the installer for this particular product isn't reliable when you uninstall and then reinstall the ADK. The problem turned out to be that the PATH variable hadn't been updated on the second install, so the PowerShell module that was invoking the DISM.exe executable wasn't able to find the required DLLs, even though they were in the same path as the executable. Go figure.
Sunday, July 24, 2016
Managing MSMQ through PowerShell
Enabling MSMQ in Windows via PowerShell
First, let's start off by seeing which Windows features for MSMQ are available in your installation:
If you see a message like "Failed to load program with incorrect format", double check that you're running a 64-bit version of PowerShell if your machine is running a 64-bit version of Windows.
Then, let's enable the ones we actually need:
if ($packagesRequiringRestart.Count -gt 0)
{
Restart-Computer
}
This script takes the packages with MSMQ in the name, enables them along with any requisite parent features and prevents restart during installation. Once complete, we check the results to see if any installations require a restart. If there are any that require a restart, we restart the computer. As with anything else in PowerShell, and IT in general, use judgement and critical thinking.
IMPORTANT: The Get-WindowsOptionalFeature cmdlet and associated module are part of the DISM module. This module is available built-in with Windows Server 2012 and up. In Windows 7 / Windows Server 2008, it's available as part of the Windows Assessment and Deployment Kit available here. Even though the page says the installer is for Windows 8.1, it works on Windows 7 / Server 2008
Get-WindowsOptionalFeature -Online | ? { $_.FeatureName -like '*msmq*' }
If you see a message like "Failed to load program with incorrect format", double check that you're running a 64-bit version of PowerShell if your machine is running a 64-bit version of Windows.
Then, let's enable the ones we actually need:
$packageResults = @(Get-WindowsOptionalFeature -Online | ? { $_.FeatureName -like '*msmq*' -and $_.State -ne 'Enabled' } | Enable-WindowsOptionalFeature -Online -All -NoRestart)
$packagesRequiringRestart = @($packageResults | ? { $_.RestartNeeded })if ($packagesRequiringRestart.Count -gt 0)
{
Restart-Computer
}
This script takes the packages with MSMQ in the name, enables them along with any requisite parent features and prevents restart during installation. Once complete, we check the results to see if any installations require a restart. If there are any that require a restart, we restart the computer. As with anything else in PowerShell, and IT in general, use judgement and critical thinking.
IMPORTANT: The Get-WindowsOptionalFeature cmdlet and associated module are part of the DISM module. This module is available built-in with Windows Server 2012 and up. In Windows 7 / Windows Server 2008, it's available as part of the Windows Assessment and Deployment Kit available here. Even though the page says the installer is for Windows 8.1, it works on Windows 7 / Server 2008
Labels:
2008,
2012,
adk,
enable,
feature,
install,
msmq,
optional,
powershell,
server,
wadk,
windows
Thursday, July 14, 2016
Configuration a web application for Application Warmup in IIS
Further to one of my previous blog posts about how to configure an ASP.NET web application for Application Initialization (warmup), here's the follow up: a powershell script for configuring the corresponding IIS application for warmup:
<#
.SYNOPSIS
Sets the required settings in the applicationHost.config file for an application to be able to automatically
initialize.
.PARAMETER WebSitePath
The name of the web application that's to have it's settings configured for application warmup.
.PARAMETER RestartService
A switch to indicate that the W3SVC (IIS) service should be restarted after the change.
#>
function Set-WebApplicationInitialization
{
[CmdletBinding(SupportsShouldProcess = $true)]
Param(
[Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string] $WebSitePath,
[Parameter(Mandatory = $false)][switch] $RestartService
)
$pathElements = $WebSitePath.Split('/')
$site = $pathElements[0]
$appSubPath = @($pathElements | select -Skip 1) -join '/'
$webApp = Get-WebApplication -Site $site -Name $appSubPath
if ($webApp -eq $null)
{
throw "Failed to find application '$appSubPath' under web site '$site'"
}
if ($PSCmdlet.ShouldProcess($WebSitePath, "Update application to use Application Initialization settings"))
{
$appPoolPath = "IIS:\AppPools\$($webApp.applicationPool)"
Set-ItemProperty -Path $appPoolPath -Name 'autoStart' -Value 'true'
Set-ItemProperty -Path $appPoolPath -Name 'startMode' -Value 'AlwaysRunning'
Set-ItemProperty -Path $appPoolPath -Name 'processModel.idleTimeout' -Value '00:00:00'
$applicationPath = "IIS:\Sites\$($WebSitePath)"
Set-ItemProperty -Path $applicationPath -Name 'preloadEnabled' -Value $true
Write-Verbose "Updated properties for web application '$appSubPath' running on pool '$($webApp.applicationPool)'"
if ($RestartService.ToBool())
{
if ($PSCmdlet.ShouldProcess("W3SVC", "Restart web service"))
{
Restart-Service W3SVC
}
}
}
}
Tuesday, June 21, 2016
PowerShell script to execute an Entity Framework Migration
I got sick and tired of coming up with hacks for including Entity Framework migrations as part of my deployment processes, so I came up with a much cleaner hack in the form of a PowerShell script that can be used to execute a database migration given an assembly and a connection string. This script does have one caveat though: for some reason if it's run more than once in a given PowerShell session, it causes a stack overflow exception, and I haven't been able to figure out why. I guess I'll have to leave it as an exercise to you. Have at it:
Param(
[ValidateNotNullOrEmpty()][string]$assemblyFile,
[ValidateNotNullOrEmpty()][string]$connectionString
# [ValidateNotNullOrEmpty()][string]$server,
# [ValidateNotNullOrEmpty()][string]$databaseName,
# [ValidateNotNullOrEmpty()][string]$userName,
# [ValidateNotNullOrEmpty()][string]$password
)
$assemblyFolder = [System.IO.Path]::GetDirectoryName($assemblyFile)
$OnAssemblyResolve = [System.ResolveEventHandler] {
param($sender, $e)
# First load the assemblies already in our app domain
foreach($a in [System.AppDomain]::CurrentDomain.GetAssemblies())
{
if ($a.FullName -eq $e.Name)
{
return $a
}
}
$fn = Join-Path $assemblyFolder "$($e.Name.Split(',')[0]).dll"
if (Test-Path $fn)
{
$ass = [Reflection.Assembly]::LoadFile($fn)
return $ass
}
return $null
}
[System.AppDomain]::CurrentDomain.add_AssemblyResolve($OnAssemblyResolve)
Set-Location ($assemblyFolder)
[System.Reflection.Assembly] $assembly = [System.Reflection.Assembly]::LoadFile($assemblyFile)
$types = $null
try
{
$types = $assembly.GetTypes()
}
catch [Exception]
{
$ErrorMessage = $_.Exception.Message
throw "Failed to load types from assembly"
}
$configurationType = [System.Type]::GetType("System.Data.Entity.Migrations.DbMigrationsConfiguration, EntityFramework")
$migratorType = [System.Type]::GetType("System.Data.Entity.Migrations.DbMigrator, EntityFramework")
$connectionInfoType = [System.Type]::GetType("System.Data.Entity.Infrastructure.DbConnectionInfo, EntityFramework")
if ($configurationType -eq $null -or $migratorType -eq $null -or $connectionInfoType -eq $null)
{
throw "Failed to load entity framework"
}
$migrationConfigurationTypes = @($types | ? { $configurationType.IsAssignableFrom($_) })
if ($migrationConfigurationTypes.Length -ne 1)
{
throw "Failed to find single migration type for Entity framework in the assembly to migrate, found $($migrationConfigurationTypes.Length) migration configuration types"
}
Write-Warning "If you see an error similar to 'Could not find a connection string named [connection string name] in the application config', try changing your DbContext descendent to use the DbContext('connection string name') constructor syntax instead of DbContext('name=connection string name'). This is a known bug in EntityFramework."
#$builder = New-Object System.Data.SqlClient.SqlConnectionStringBuilder
# Need to use psbase, otherwise these properties throw an exception
#$builder.psbase.DataSource = $server
#$builder.psbase.InitialCatalog = $databaseName
#$builder.psbase.UserID = $userName
#$builder.psbase.Password = $password
#$connectionString = $builder.ToString()
$configuration = [System.Activator]::CreateInstance($migrationConfigurationTypes[0])
$connectionInfo = New-Object $connectionInfoType ($connectionString, "System.Data.SqlClient")
$configuration.TargetDatabase = $connectionInfo
$migrator = [System.Activator]::CreateInstance($migratorType, @($configuration))
$migrator.Update()
Write-Host 'Successfully migrated database'
Monday, April 04, 2016
Creating your own repository for PowerShell modules
Apparently it's quite easy, according to Microsoft. All you need is a slightly tweaked NuGet repository.
Labels:
feed,
library,
modules,
NuGet,
powershell,
repository,
scripts
Friday, February 12, 2016
Getting the Active Directory cmdlets (for scripted and remote management of your Windows Server machines)
To get the cmdlets, you'll need to install the Remote Server Administration Tools, available here.
Alternatively, you can follow the instructions on this blog: http://www.itgeared.com/articles/1072-how-to-install-rsat-on-windows-server_21/
Alternatively, you can follow the instructions on this blog: http://www.itgeared.com/articles/1072-how-to-install-rsat-on-windows-server_21/
Tuesday, December 08, 2015
Getting the SQL Server PowerShell tools
They're apparently not that easy to find. The SQL Server PowerShell Tools come as part of the SQL Server Feature Pack for their respective versions. You can find the SQL Server 2014 Feature Pack (along with the PowerShell Tools) here.
Thursday, October 22, 2015
Querying PowerShell for module and cmdlet information
I've recently realized that it's of incredible benefit to start designing our systems such that they're open and easily queryable by any system, particularly .NET and PowerShell. As a result, I've started designing modules for PowerShell to let my team administrate our systems. This has led me to realize that they need some of the basics of PowerShell to query what's available to them, because none of them have really used PowerShell before. The following commands should be of help to beginners:
Show the currently loaded PowerShell modules: Get-Module
Show the available PowerShell modules: Get-Module -ListAvailable
Show the cmdlets available in a particular module: Get-Command -Module [module name]
* in the case of our custom compiled C# module assembly, this is the name of the assembly (not the name of the assembly file, e.g. MyCompany.MyAssembly, not MyCompany.MyAssembly.dll)
Show the currently loaded PowerShell modules: Get-Module
Show the available PowerShell modules: Get-Module -ListAvailable
Show the cmdlets available in a particular module: Get-Command -Module [module name]
* in the case of our custom compiled C# module assembly, this is the name of the assembly (not the name of the assembly file, e.g. MyCompany.MyAssembly, not MyCompany.MyAssembly.dll)
Sunday, October 18, 2015
Accessing TFS via PowerShell
I'm ashamed to admit that only today did I find out that there are PowerShell cmdlets for TFS.
You can load them into a PowerShell session by executing this:
add-pssnapin Microsoft.TeamFoundation.PowerShell
Once that's done, you can get started with the following commands:
Get-Help Get-TfsServer
See this post on Hey Scripting Guy.
You can load them into a PowerShell session by executing this:
add-pssnapin Microsoft.TeamFoundation.PowerShell
Once that's done, you can get started with the following commands:
Get-Help Get-TfsServer
See this post on Hey Scripting Guy.
Thursday, June 04, 2015
Getting started with Azure in PowerShell
As it turns out, Azure has a ton of cmdlets available in the PowerShell command line to help you quickly and easily manage aspects of Azure.
- Install the Azure PowerShell from the Microsoft Web Platform Installer
- Install the Azure AD Module from the links on this page.
- After installing the Microsoft Online pack, you may have to copy the 'MSOnline' and 'MSOnlineExtended' folders from 'C:\windows\system32\WindowsPowerShell\v1.0\Modules' to 'C:\Windows\SysWOW64\WindowsPowerShell\v1.0\Modules' if you're running a server version of Windows
- Open a PowerShell session as Administrator
- Run the command "Import-Module azure"
- Run the command "Import-Module MSOnline"
- Add-AzureAccount -- Allows you to enter credentials and register your account with PowerShell so that you can manage it
- Get-AzureAccount -- shows you the currently active accounts
- Get-AzureSubscription -- shows the subscriptions available for the currently selected azure account
Also, to manage the roles in your Azure Active Directory, check out this page on Microsoft's Azure section.
To start log streaming for a specific web application, use this command:
PS C:\> Get-AzureWebsiteLog -Tail -Name mywebsitenamehere
Beginning in version 0.8.0, the Azure PowerShell installation includes more than one PowerShell module. You must explicitly decide whether to use the commands that are available in the Azure module or the Azure Resource Manager module. To make it easy to switch between them, we have added a new cmdlet, Switch-AzureMode, to the Azure Profile module.
When you use Azure PowerShell, the cmdlets in the Azure module are imported by default. To switch to the Azure Resource Manager module, use the Switch-AzureMode cmdlet. It removes the Azure module from your session and imports the Azure Resource Manager and Azure Profile modules.
To switch to the AzureResoureManager module, type:
PS C:\> Switch-AzureMode -Name AzureResourceManager
To switch back to the Azure module, type:
PS C:\> Switch-AzureMode -Name AzureServiceManagement
By default, Switch-AzureMode affects only the current session. To make the switch effective in all PowerShell sessions, use the Global parameter of Switch-AzureMode.
To start log streaming for a specific web application, use this command:
PS C:\> Get-AzureWebsiteLog -Tail -Name mywebsitenamehere
Friday, January 16, 2015
Querying XML with namespaces in PowerShell
Apparently it's ridiculously easy to parse XML in PowerShell once you have the right objects set up:
In this example, I query a deployment configuration for attributes called "ServerHostName" within the XML namespace "http://www.mycompany.com/Some/Namespace/Deployment/DeploymentProfiles.xsd". This was exceptionally useful today when I quickly needed to figure out what servers my system was using and send that information to others to configure those servers.
[xml] $xml = Get-Content .\DeploymentProfile.PRODUCTION.xml
$ns = new-object Xml.XmlNamespaceManager $xml.NameTable
$ns.AddNamespace('dns', 'http://www.mycompany.com/Some/Namespace/Deployment/DeploymentProfiles.xsd')
$xml.SelectNodes("//@dns:ServerHostName", $ns) | ForEach-Object { $_.Value } | sort | Get-Unique
In this example, I query a deployment configuration for attributes called "ServerHostName" within the XML namespace "http://www.mycompany.com/Some/Namespace/Deployment/DeploymentProfiles.xsd". This was exceptionally useful today when I quickly needed to figure out what servers my system was using and send that information to others to configure those servers.
Labels:
namespace,
namespaces,
parsing,
powershell,
XML,
xpath,
xquery
Adding a computer to the local machine's list of PowerShell TrustedHosts
Retrieve the current list:
$curValue = (get-item wsman:\localhost\Client\TrustedHosts).value
Set the new list, appending the new host onto the old list:
set-item wsman:\localhost\Client\TrustedHosts -value "$curValue, Server01.Domain01.Fabrikam.com"
$curValue = (get-item wsman:\localhost\Client\TrustedHosts).value
Set the new list, appending the new host onto the old list:
set-item wsman:\localhost\Client\TrustedHosts -value "$curValue, Server01.Domain01.Fabrikam.com"
Wednesday, August 20, 2014
Getting an "RPC endpoint not found/not listening" exception when connecting to a remote machine with PowerShell
Lately I've been dealing with a lot of remote management for the purposes of automating our deployment process for the product on which I'm working. I've been able to connect other (pre-configured) machines, but when I wanted to connect to my own machine in unit tests, I've been unable to do so until now. Each time I try to connect, I'd get an exception along the lines of "The remote RPC server is not responding". I double checked that my "Windows Remote Management (WS-Management)" service is up and running, so I was perplexed as to why I still couldn't connect. I had turned off my firewall (temporarily, of course), and as if that wasn't enough, I'd explicitly enabled the rules for Windows Remote Management. As it turns out, (at least when you're running Windows Server 2008 R2) the service runs by default, but is not configured to allow remote management by default. (Totally makes sense, right ? /sarcasm) To remedy this, you need only run the following under and Administrator command line:
winrm quickconfig
This will enable your machine to accept incoming connections. You should also ensure that your firewall has been properly configured to allow the remote management rules (pre-existing, come with Windows). Also make sure that your service is actually running.
winrm quickconfig
This will enable your machine to accept incoming connections. You should also ensure that your firewall has been properly configured to allow the remote management rules (pre-existing, come with Windows). Also make sure that your service is actually running.
Monday, May 26, 2008
How to recurlively delete a folder and its contents in PowerShell
The command :
The really sad thing is that I googled this and there are no sites that explicitly state how to do this. The comparable command in bash :
Yet one more reason I hate Microsoft and PowerShell in particular.
Remove-Item -recurse -force [directory name]
The really sad thing is that I googled this and there are no sites that explicitly state how to do this. The comparable command in bash :
rm -rf [directory name]
Yet one more reason I hate Microsoft and PowerShell in particular.
Subscribe to:
Posts (Atom)