webmd-health-services / carbon Goto Github PK
View Code? Open in Web Editor NEWLicense: Apache License 2.0
License: Apache License 2.0
If importing Carbon within a Chocolatey installChocolatey.ps1 Script, the Chocolatey Function
Install-ChocolateyEnvironmentVariable
uses a Function Set-EnvironmentVariable
, which conflicts with the Carbon Function.
Errormessage:
ERROR: A parameter cannot be found that matches parameter name 'Scope'.
Carbon overrides the the Chocolatey Function Set-EnvironmentVariable which causes the Error.
Reported by a user on chocolatey.org:
I'm having trouble uninstalling carbon, I noticed that it was because of a trailing ';' in my PSModulePath environment variable.
Could you fix your uninstall script so that it doesn't crash when there is a ';' in front or at the back of the PSModulePath variable?
You just need to add the following line after the for ForEach-Object
Where-Object {$_} |
These functions return values when they create a new hosts file. Change this:
Occasionally, when running Set-HostsEntry, I'll get an error about not being able to access the hosts file because another process has it locked. If I wait about 10-15 seconds and check the hosts file, all of my entries are gone.
I've had this happen a few times, but can't reproduce it consistently. It seems to happen when there are multiple calls to Set-HostsEntry in succession. But when it does happen, it's extremely annoying.
Chocolatey now requires VERIFICATION.txt file in the package. Get it added to the package, please: https://github.com/chocolatey/package-validator/wiki/VerificationFileMissing
Carbon_Service dsc resource only accepts "path" for the service, not the "argument" parameter, even tho the "argument" parameter is exposed by the underlying install-service function
Create a function that will parse the hosts file and return objects for each line. Each object should have IPAddress, HostName, Comments properties.
There are a couple of problems with this latest release. The Get-WindowsFeature.ps1, Install-WindowsFeature.ps1, and Uninstall-WindowsFeature.ps1 scripts were changed to check for Get-CWindowsFeature* before they create that function, but that is wrong. You should still be checking for Get-WindowsFeature* as that is the thing you are trying to simulate if not available. Also, since you are creating aliases for all of the functions listed in Carbon.psd1, you are effectively not solving the original problem of not clobbering existing functions. I have made changes to my local copy and attached them if you would like to review them for inclusion. I think the idea of aliasing the renamed functions is a mistake that you should look at hard for the next release. I would not alias and note that the release causes breaking changes. Another approach would be to allow for aliases with a switch of some kind, but I feel that should be a stop-gap measure as the sooner you get totally away from name collisions the better.
Carbon_Updates.zip
The following test fixture don't clean up after themselves:
Directories:
Files:
Update Set-IisWebsiteID to write a verbose message showing when it sets/updates a site's ID.
Carbon_Permission resource currently doesn't support multiple ACL entries for a principal.
E.g. we need to set permissions ("ReadAndExecute", "ContainerAndSubContainersAndLeaves") and ("Write", "ContainerAndLeaves") for a user on a folder.
Remove all the application configuration file code from Invoke-PowerShell. Carbon only support PowerShell 4, which runs under .NET 4 and doesn't run on later versions.
The Install-CService
function always shows a verbose message.
Invoke-WebRequest fails if the user running it hasn't performed the first launch experience. This experience can be disabled by creating a DisableFirstRunCustomize DWORD value greater than 0 under one of these keys:
"HKEY_LOCAL_MACHINE\\Software\\Policies\\Microsoft\\Internet Explorer\\Main",
"HKEY_CURRENT_USER\\Software\\Policies\\Microsoft\\Internet Explorer\\Main",
"HKEY_CURRENT_USER\\Software\\Microsoft\\Internet Explorer\\Main",
"HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Internet Explorer\\Main"
Create a Disable-IEFirstLaunchExperience and Enable-IEFirstLaunchExperience. They should have two switches, -LocalMachine and -CurrentUser, to set the flag for those two users, respecively.
Also, create a Test-IEFirstLaunchExperience function that tests if a user has already run the first launch experience. The Enable/Disable function should use this function and only Enable/Disable if the user hasn't completed the first launch experience. Of course, this should only happen if the -CurrentUser switch.
I'm trying to use Get-Certificate
to examine a number of .cer
files in a directory, eg:
C:\> get-command get-certificate
CommandType Name Version Source
----------- ---- ------- ------
Function Get-Certificate 2.6.0 Carbon
C:\> get-certificate C:\tmp\Certificates\*.cer|fl *
This lists the details from each of the .cer
files OK, but I can't see anything which shows me which file each entry is from. Am I missing something? Is there a way to get the path(/filename) returned?
Update Install-IisVirtualDirectory so that it can create a virtual directory under an application. It may already do this. If so, add an example to the documentation.
Hi,
It would be nice to have a Get-HostsEntry function to retrieve an entry from the hosts file.
Even more useful would be to have a DSC resource to set an entry in the host file.
If I have a PR for this would you be ok to merge it?
Thanks
Create functions to managing a website in IE's security zones. Use the IInternetSecurityManager API.
#!C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using Carbon.Win32;
namespace Carbon.InternetExplorer
{
[ComImport, GuidAttribute("79EAC9EE-BAF9-11CE-8C82-00AA004BA90B")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IInternetSecurityManager
{
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int SetSecuritySite([In] IntPtr pSite);
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int GetSecuritySite([Out] IntPtr pSite);
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int MapUrlToZone([In, MarshalAs(UnmanagedType.LPWStr)] string pwszUrl, ref UInt32 pdwZone, UInt32 dwFlags);
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int GetSecurityId([MarshalAs(UnmanagedType.LPWStr)] string pwszUrl, [MarshalAs(UnmanagedType.LPArray)] byte[] pbSecurityId, ref UInt32 pcbSecurityId, uint dwReserved);
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int ProcessUrlAction([In, MarshalAs(UnmanagedType.LPWStr)] string pwszUrl, UInt32 dwAction, out byte pPolicy, UInt32 cbPolicy, byte pContext, UInt32 cbContext, UInt32 dwFlags, UInt32 dwReserved);
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int QueryCustomPolicy([In, MarshalAs(UnmanagedType.LPWStr)] string pwszUrl, ref Guid guidKey, ref byte ppPolicy, ref UInt32 pcbPolicy, ref byte pContext, UInt32 cbContext, UInt32 dwReserved);
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int SetZoneMapping(UInt32 dwZone, [In, MarshalAs(UnmanagedType.LPWStr)] string lpszPattern, UInt32 dwFlags);
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int GetZoneMappings(UInt32 dwZone, out IEnumString ppenumString, UInt32 dwFlags);
}
public enum SecurityZone
{
Local = 0,
Intranet = 1,
Trusted = 2,
Internet = 3,
Restricted = 4
}
public static class SecurityManager
{
private static readonly Guid _CLSID_SecurityManager = new Guid("7b8a2d94-0ac9-11d1-896c-00c04fb6bfc4");
private static readonly Type comSecurityManagerType = Type.GetTypeFromCLSID(_CLSID_SecurityManager);
private static readonly IInternetSecurityManager ism = Activator.CreateInstance(comSecurityManagerType) as IInternetSecurityManager;
public static string[] GetZoneMappings(SecurityZone zone)
{
IEnumString enumStrings;
var strings = new List<string>();
var result = ism.GetZoneMappings((uint)zone, out enumStrings, 0);
if (result == Win32ErrorCodes.Ok)
{
var item = new string[1];
var numFetched = new IntPtr();
while (enumStrings.Next(1, item, numFetched) == Win32ErrorCodes.Ok && numFetched.ToInt32() > 0)
{
strings.Add(item[0]);
}
return strings.ToArray();
}
return new string[0];
}
public static SecurityZone GetSecurityZone(string url)
{
var uri = new Uri(url);
if (uri.Scheme != "http" && uri.Scheme != "https")
{
throw new ArgumentException("URL must begin with \"http://\" or \"https://\".");
}
// ReSharper disable once InconsistentNaming
uint zoneID = 0;
var result = ism.MapUrlToZone(url., ref zoneID, 0);
if ( result == Win32ErrorCodes.Ok)
{
return (SecurityZone) zoneID;
}
throw new Win32Exception(result);
}
}
}
#!C#
using System;
using Carbon.InternetExplorer;
using NUnit.Framework;
namespace Carbon.Test.InternetExplorer
{
[TestFixture]
public sealed class SecurityManagerTestFixture
{
[Test]
public void ShouldGetMappsings()
{
foreach (SecurityZone zone in Enum.GetValues(typeof (SecurityZone)))
{
var strings = SecurityManager.GetZoneMappings(zone);
foreach (var item in strings)
{
Console.WriteLine(item);
}
}
}
[Test]
public void ShouldGetSecurityZone()
{
Console.WriteLine(SecurityManager.GetSecurityZone("http://google.com"));
}
}
}
Update Import-Carbon.ps1 and Carbon.psm1 to check Carbon for blocked files and return a sensible error to the user.
gci . -Recurse | gi -Stream Zone.Identifier -ea ignore
Carbon should fully support the -WhatIf parameter. Review and find places where it is missing.
Rename the Protect-Acl and Unprotect-Acl functions to Disable-AclInheritance and Enable-AclInheritance, respectively. Protect/Unprotect is used for encrypting things.
There is a bug in PowerShell that prevents searching through a certificate store over remoting. This causes Unprotect-String to fail when given a thumbprint because it searches for a certificate using wildcards, e.g.:
Get-ChildItem "cert:\*\*\$Thumbprint"
Add StoreLocation and StoreName parameters to Unprotect-String so users can specify a specific location.
Make it easier to add an item to an environment variable that is a list (e.g. PATH). Add a Delimiter parameter that defaults to a semicolon. Figure out a way to remove an item for a list. Create Get-EnvironmentVariable function that can return a variable as a list.
Members returned are:
Name, RequiredServices, Disposed, Close ,Continue ,CreateObjRef, Dispose, Equals, ExecuteCommand, GetHashCode, GetLifetimeService, GetType, InitializeLifetimeService, Pause, Refresh, Start, Stop, WaitForStatus, CanPauseAndContinue, CanShutdown, CanStop, Container, DependentServices, DisplayName, MachineName, ServiceHandle, ServiceName, ServicesDependedOn, ServiceType, Site, StartType, Status, ToString
This means the TestScript always returns $false when specifying unsupported keys such as OnFirstFailure.
Install-Certificate should only install a certificate if it doesn't exist in a store. Add a -Force parameter to preserver old behavior.
http://www.leeholmes.com/blog/2010/09/24/adjusting-token-privileges-in-powershell/
Create a Get-ParentPID function which returns a process's parent PID using the Win32 API:
http://stackoverflow.com/questions/185254/how-can-a-win32-process-get-the-pid-of-its-parent
Update the Process type data to call this function instead of WMI. Make sure this method is faster than WMI.
Here's the code:
#include <stdio.h>
#include <windows.h>
#include <tlhelp32.h>
int main(int argc, char *argv[])
{
int pid = -1;
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 pe = { 0 };
pe.dwSize = sizeof(PROCESSENTRY32);
//assume first arg is the PID to get the PPID for, or use own PID
if (argc > 1) {
pid = atoi(argv[1]);
} else {
pid = GetCurrentProcessId();
}
if( Process32First(h, &pe)) {
do {
if (pe.th32ProcessID == pid) {
printf("PID: %i; PPID: %i\n", pid, pe.th32ParentProcessID);
}
} while( Process32Next(h, &pe));
}
CloseHandle(h);
}
The Convert-XmlFile
returns extra values. Update it so that it doesn't.
In the help and the web page, Grant-HttpUrlAclPermission
is written, in the help text and examples, instead of the correct command Grant-HttpUrlPermission
Create a Get-IisLockedConfigSections function which returns a list of all the locked configuration sections on a computer. It should take no parameters and parse the output to the following appcmd command:
#!powershell
C:\Windows\System32\inetsrv\appcmd.exe unlock config /section:? -xml
update the documentation for the Unlock-IisConfigSection function to reference the new function.
On Server OSes, If Carbon is present on the module load path and a script uses the Get-WindowsFeature
cmdlet, it throws a CommandNotFoundException
unless the ServerManager
module is explicitly imported first.
To reproduce:
PS> Get-Command Get-WindowsFeature
CommandType Name Version Source
----------- ---- ------- ------
Cmdlet Get-WindowsFeature 2.0.0.0 ServerManager
PS> Install-Module Carbon -AllowClobber
PS> Get-WindowsFeature
Get-WindowsFeature : The term 'Get-WindowsFeature' is not recognized as the name of a cmdlet, function, script file,
or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and
try again.
At line:1 char:1
+ Get-WindowsFeature
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Get-WindowsFeature:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
I realize Carbon probably implemented Get-WindowsFeature
before ServerManager
did, but sometimes it isn't possible to control what modules are loaded ahead of time, such as in OneGet/MicrosoftDockerProvider#26. The fact that a CommandNotFoundException
occurs is also very confusing and hides the underlying issue.
Environment info:
$PSVersionTable
:Name Value
---- -----
PSVersion 5.1.14393.2515
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.14393.2515
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
Create about_Carbon_objects help topic to document Carbon's compiled objects.
Update Install-Certificate to not return a certificate object.
Create functions fore creating/removing files.
Logs from AppVeyor:
[00:02:59.25] [PowerShell] .\Start-CarbonTest.ps1
The term '' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
at , C:\projects\carbon\Carbon\Carbon.psm1: line 2725
at , C:\projects\carbon\Carbon\Import-Carbon.ps1: line 64
at , C:\projects\carbon\Carbon\Import-Carbon.ps1: line 44
at , C:\projects\carbon\Start-CarbonTest.ps1: line 28
at , : line 82
+ CategoryInfo : ObjectNotFound: (:String) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : CommandNotFoundException
+ PSComputerName : localhost
The module to process 'Carbon.psm1', listed in field 'ModuleToProcess/RootModule' of module manifest 'C:\projects\carbon\Carbon\Carbon.psd1' was not processed because no valid module was found in any module directory.
at , C:\projects\carbon\Carbon\Import-Carbon.ps1: line 64
at , C:\projects\carbon\Carbon\Import-Carbon.ps1: line 44
at , C:\projects\carbon\Start-CarbonTest.ps1: line 28
at , : line 82
+ CategoryInfo : ResourceUnavailable: (Carbon:String) [Import-Module], PSInvalidOperationException
+ FullyQualifiedErrorId : Modules_ModuleFileNotFound,Microsoft.PowerShell.Commands.ImportModuleCommand
+ PSComputerName : localhost
C:\projects\carbon\Start-CarbonTest.ps1 : The term 'Get-PowerShellModuleInstallPath' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was
included, verify that the path is correct and try again.
at , C:\projects\carbon\Start-CarbonTest.ps1: line 30
at , : line 82
+ CategoryInfo : ObjectNotFound: (Get-PowerShellModuleInstallPath:String) [Start-CarbonTest.ps1], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException,Start-CarbonTest.ps1
at Write-WhiskeyInfo, C:\projects\carbon\PSModules\Whiskey\0.44.0\Whiskey.psm1: line 6731
at Write-WhiskeyError, C:\projects\carbon\PSModules\Whiskey\0.44.0\Whiskey.psm1: line 6591
at , : line 88
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Write-WhiskeyInfo
+ PSComputerName : localhost
VERBOSE: [00:02:59.91] [PowerShell] Exit Code 0
VERBOSE: [00:02:59.92] [PowerShell] $? False
VERBOSE: [00:02:59.98] [PowerShell] FAILED in 00:00:02.4139742
VERBOSE: [00:02:59.98] [PowerShell]
VERBOSE: [00:02:59.99] [PowerShell] FAILED in 00:00:03.9679738
VERBOSE: [00:02:59.99] [PowerShell]
Uploading artifact appveyor_APPVYR-WIN_2020-01-05_21_01_33.trx (54,083 bytes)...100%
Uploading artifact dotnet.publish.Carbon.Test.csproj.log (951,410 bytes)...100%
Uploading artifact dotnet.test.Carbon.Test.csproj.log (157,583 bytes)...100%
Uploading artifact msbuild.Carbon.csproj.log (390,764 bytes)...100%
Uploading artifact msbuild.Carbon.Iis.csproj.log (388,170 bytes)...100%
Uploading artifact msbuild.Carbon.sln.log (3,637,192 bytes)...100%
Uploading artifact msbuild.Carbon.Xdt.csproj.log (380,528 bytes)...100%
Uploading artifact nunit3+uvlq5egf.2fj.xml (33,668 bytes)...100%
The running command stopped because the preference variable "ErrorActionPreference" or common parameter is set to Stop: C:\projects\carbon\whiskey.yml: Task "PowerShell": PowerShell script ".\Start-CarbonTest.ps1" threw a terminating exception.
Use the Win32_NetworkAdapterConfiguration WMI class to validate that a website is binding to a valid IP address. Write a warning if it isn't.
> Install-Module -Name Carbon -Force
PackageManagement\Install-Package : The following commands are already available on this
system:'Get-FileShare,Get-ScheduledTask,Set-EnvironmentVariable,Get-Certificate'. This module 'Carbon' may
override the existing commands. If you still want to install this module 'Carbon', use -AllowClobber parameter.
At C:\Program Files\WindowsPowerShell\Modules\PowerShellGet\1.1.2.0\PSModule.psm1:1809 char:21
+ ... $null = PackageManagement\Install-Package @PSBoundParameters
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (Microsoft.Power....InstallPackage:InstallPackage) [Install-Pa
ckage], Exception
+ FullyQualifiedErrorId : CommandAlreadyAvailable,Validate-ModuleCommandAlreadyAvailable,Microsoft.PowerSh
ell.PackageManagement.Cmdlets.InstallPackage
Some of these commands already exist natively in Windows 10. See: https://technet.microsoft.com/en-us/library/mt774137.aspx and https://technet.microsoft.com/en-us/library/hh848632.aspx
Should these commands be renamed?
Fubar
Create an Update-XmlFile function which will add XML elements/attributes to an XML file.
$element = [xml] '<endpoint address="" binding="" />'
Set-Xml -Path machine.config -Element '<system.serviceModel />' -ChildOf '/configuration'
Set-Xml -Path machine.config -Element '<behaviors />' -ChildOf '/configuration/system.serviceModel'
Set-Xml -Path machine.config -Element '<client>' -ChildOf '/configuration/system.serviceModel/behaviors'
Set-Xml -Path machine.config -Element $element -ChildOf '/configuration/system.serviceModel/behaviors/client'
We are using a couple DSC resources from Carbon in out DSC configurations and I have noticed in the past that on servers running DSC, we couldn't delete the Carbon module if we needed to because files were in use. I ran Process Explorer on one of the servers and the WmiPrvSE.exe process is in fact using several files from the Carbon module, even after the consistency check has completed. Specifically, the following files are being used:
\Carbon\2.2.0\bin\Carbon.lis.dll
\Carbon\2.2.0\bin\Carbon.dll
\Carbon\2.2.0\bin\Ionic.Zip.dll
These files stay in use for at least a few minutes (maybe longer) after a consistency check runs, making the module hard to delete.We have some other custom resources that were developed in house where this is not the case. No files get locked up during or after the consistency check. I'm not sure if this is a Carbon specific thing or a PowerShell/DSC specific thing.
If a certificate is of the type that gets stored in the CNG store and not the CryptoAPI store, then the Grant-CPermission cannot find it and errors. This is how I handled it in my code, maybe you can include this capability in Carbon:
# legacy CryptoAPI store
if ($MyCert.PrivateKey)
{
$MyCertPath = $CertPath + '\' + $MyCert.Thumbprint
Grant-CPermission -Identity $ServiceUser -Permission 'GenericRead' -Path $MyCertPath
}
# CNG store
else
{
# Identify the user you'll be granting permission to
$Grantee = New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList ($ServiceUser)
$rsaCert = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($MyCert)
$CertFile = $rsaCert.key.UniqueName
$MyCertPath = "$env:ALLUSERSPROFILE\Microsoft\Crypto\Keys\$CertFile"
$CertPermissions = Get-Acl -Path $MyCertPath
$access_rule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList ($Grantee, 'Read', 'None', 'None', 'Allow')
$CertPermissions.AddAccessRule($access_rule)
Set-Acl -Path $MyCertPath -AclObject $CertPermissions
}
function Expand-Byte
{
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[byte[]]
# The bytes to expand.
$Byte
)
$inStream = New-Object IO.MemoryStream (,$Byte)
$gzStream = New-Object IO.Compression.GZipStream $inStream,Decompress
$outStream = New-Object IO.MemoryStream
try
{
$chunkSize = 4096
$unzipBytes = New-Object 'System.Byte[]' $chunkSize
while( $true )
{
$sizeRead = $gzStream.Read( $unzipBytes, 0, $chunkSize )
if( $sizeRead -gt 0 )
{
$outStream.Write( $unzipBytes, 0, $chunkSize )
}
else
{
break
}
}
$outStream.ToArray()
}
finally
{
$outStream.Close()
$gzStream.Close()
$inStream.Close()
} }
Add a Today
script property to DateTime that returns today's date, with no time:
New-Object DateTime $this.Year,$this.Month,$this.Day
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.