
Probably, in your work, like me, you often have to deal with IT systems of companies that were incomprehensible to you and how they were served. Before fully supplying the company for maintenance, it is imperative to do an IT Audit and put all the systems in order.
Often one of the systems where there is no order is the 1C system. For example, you can find databases with the name of the folders
"new_copybase1_old" or
"Base1CompanyZP" , or in general folders nested in each other.
')
Who and what has access to these databases is sometimes extremely difficult to determine. Lists of databases on client computers, in the application 1C, can also be called incomprehensible. In general, not a very happy picture.
If it is time for you to bring all the databases to one common standard and automate the connection of users, then I ask for cat.
To bring all the bases to a common standard, to bring order - everything is good! But how to do it most quickly and efficiently?
Search for a ready solution
A search on the web showed that the best articles on this topic are on Habré:
1.
“Managing lists of 1C 8.2 databases” ;
2.
"How to prepare hundreds of bases 1C and not go crazy" ;
3.
"Managing the list of 1C 8.2 databases using Active Directory" ;
4.
"Easy management of 1C database lists .
"The article
“Easy management of 1C bases lists” by
Sergey-S-Kovalev seemed the most useful, it begins with a famous quote:
“It’s better to lose a day and then fly five minutes later” (s) m / f. Wings, legs and tails.
But not everything is so quick and easy.
So, setting up an article by the user
Sergey-S-Kovalev is to perform the steps, which are divided into 6 stages.
Stage 1 - Inventory;
Stage 2 - Groups AD for 1C databases;
Stage 3 - Configuration files 1C;
Stage 4 - File or DFS resource;
Stage 5 - Group Policy;
Stage 6 - User.
The steps in stages 1, 5 are implemented once for each of the companies, there is no routine in them, you can easily do it by hand.
The setup scheme that
Sergey-S-Kovalev offers is great! No scripts, everything works simple and clear. But you have to lose not a day, but much more if you need to customize this work scheme, for example, in 10 companies in which there can be about 200 1C bases in total.
That is, the initial setup in a large company can be very long and tedious.
I propose to automate part of the steps and reduce the number of stages.
To better understand what I’m talking about, I recommend that you first familiarize yourself with the “Easy management of 1C bases lists” .
Stage 1 - Inventory
1. Create an Excel file for a shared accounting resource, as shown in the figure.

Be sure to bring the names of old databases and folders into this file so that later it would be clear where to copy the bases from.
OldBaseName, OldFolderName . The file can be taken
here .
2. Together with the most important accountant of the company we fill in the fields:
BaseName, FolderName, GroupName, AccessUser(1-7)
- The column
BaseName
filled in manually in Russian according to the standard, for example, IP-Ivanov_BOOH. - The
FolderName
column FolderName
filled in manually in Latin according to the standard, in our case IP-IVANOV_BUH. - The name of the AD group is already generated based on the
FolderName
column, in our case GRRS_IP-IVANOV_BUH, I think you know how you can add cells in Excel based on information from other cells. - You can ask access to the databases in the AccessUser fields for the most important accountant himself, but you can also ease the work. To do this, you need to take a list of accounting records from AD, for example, using the command
Get-Aduser -searchbase "OU=Accountants, DC=domain, DC=ru" -filter * -Properties SamAccountname | FT SamAccountname
and place this list on the second sheet of our file. - Next to the AccessUser fields, you must bind this list. If you don’t know how, ask Google something like the following: “Or, just use my file.
In the end, the most important accountant simply puts down access for each database, selecting users from the list. The list can be pre-ordered by means of Excel itself, for example, place the most common accounts at the beginning.
3. After filling this file, it must be saved and copied to the directory in which the script will run.
From the file
Sergey-S-Kovalev , it differs in that it immediately gives access to users, no description, server and cluster names. In my environment, this information is superfluous and I did not include it in the file.
Stage 2 - Running the Script
Probably, you already understand that we will feed the script with the file that resulted from the first stage. The script will perform all the actions that
Sergey-S-Kovalev described in stages 2,3,4,6.
What the script will do:
1. Will create groups in AD for each base.
2.Adds the path to the folder with the database to the description field of each group.
3. In the notes field of each group, add the name of the base and the path to the folder with the base.
4. Add to user access groups according to the list.
5. Generates a common file 1CEStart.cfg with a list of all databases, and will place this file in a network folder with 1C configuration files.
6. Generates v8i-files for each database and places these files in a network folder with 1C configuration files.
7. Record the corresponding group for each v8i file in the access lists.
8.Creates folders for databases and assigns the appropriate group to the folder access lists.
In general, the script will do almost everything that
Sergey-S-Kovalev did in his article manually.
Before running the script, you need the following.
(Automation of these actions so far only in the plans)Create AD groups
1. Create in the domain OU to store groups with access to databases 1C. In my example, it will be $ OU = “OU = 1C, OU = Resources, DC = domain, DC = ru”
2. Create the group GRRS_1C_ConfigBasesRO in this OU. Add GRRS_1C_ConfigBasesRO group to “Domain computers” group
3. Create a group GRRS_1CBases in this OU.
4. Create a group GRUS_1Cadmins in this OU and add admins 1C to it (optional)
Create folders
1. Create a folder on the 1C server for storing databases. In our case it will be 1cshare.
2. The 1cshare folder must be given access to the GRRS_1CBases group for writing, in the permissions on the Share tab.
3. On the Security tab, delete the Users group and set read permissions for the GRRS_1CBases group.
4. Create a shared DFS folder in the domain or just a folder, for example, \\ domain.ru \ DfsShare \ 1cconfig \
5. This folder will contain 1C configuration files.
6. The folder \\ domain.ru \ DfsShare \ 1cconfig \ should be granted access to the group GRRS_1C_ConfigBasesRO for reading only.
It is necessary that the user, from which the script will be launched, had the right to write to the folder with databases and to the folder \\ domain.ru \ DfsShare \ 1cconfig \.
Requirements for running the script
The script reads an Excel file using Microsoft Access Database Engine 2010 Redistributable
It is better to immediately install this product on the server from which the script will run.
You can download the engine
here . It is important that the bit of the operating system matches the bit depth of the engine.
Attention! If you go to run the script from your desktop client computer, the bit depth of Microsoft Office should also match the bit width of the engine.
I recommend to install the engine on the server and not suffer with reinstalling Microsoft Office on your computer. On the computer to run the script must be installed powershell version 4.0 or higher and snap-AD with PowerShell modules.
You must also write the following variables in the script.# 1-,
$1CServer = "nn-1cserver"
# , 1.
$ShareName = "1cshare"
#OU Active Directory, 1c
$OU = “OU=1C, OU=Resources, DC=domain, DC=ru”
# DFS , 1
$1CConfigFolder = "\\domain.ru\DfsShare\1cconfig\"
# ,
$datafile = "BasesBuh.xlsx"
#
$strSheetName = 'Sheet1$'
Note: Why did I implement Excel reading, not csv? I don’t like to work with CSV, as it is necessary to follow the encoding for Cyrillic characters, also CSV is not convenient to edit. If you can read an Excel file, you can immediately slip it into any script without preparing its format.
Stage 3 - Creating a Policy for Users
Sergey-S-Kovalev very well described the creation of a policy for the operation of this scheme.
1. We implement, according to his article, copying the configuration file 1CEStart.cfg from the shared network folder to the folder on the computer% ProgramData% \ 1C \ 1CEStart \ Create this policy for computers.
2. Further, in the policy it is necessary to ensure the cleaning of the% Appdata% \ 1C \ 1CEStart \ ibases.v8i file for each user. Its new content will be formed when you first run 1C from the 1CEStart.cfg file.
Stage 4 - Copy Old Bases to New Folders
After you run the script, and it has created all the groups, folders, and files, you need to copy the old databases to a new location, that is, distribute them into new folders. Here you will be helped by the columns
OldFolderName, FolderName.Script here###########################################################
# AUTHOR : Rinat K. Nugaev - http://www.nugaev.net - rinat@nugaev.net
# DATE : 07-02-2016
# EDIT : 07-03-2016
# COMMENT : This script creates folders, groups, and other
# stuff for 1C envinronment.
# Use it for your own risk!
# VERSION : 1.2
###########################################################
# CHANGELOG
# Version 1.2: 07-03-2016 - Changed the code
# - Added DataFilePath checking
# - Added AD modules installing
# - Changed users's array creating
# - Added Russian comments
# AD PowerShell
Try
{
Import-Module ActiveDirectory -ErrorAction Stop
}
Catch
{
Write-Host "[ERROR]`t ActiveDirectory Powershell ! , !"
Write-Host "[ERROR]`t Windows 2008/2008R2 Import-Module ServerManager"
Write-Host "[ERROR]`t Add-WindowsFeature RSAT-AD-PowerShell"
Write-Host "[ERROR]`t Windows 2012/2012R2 Add-WindowsFeature RSAT-AD-PowerShell"
Exit 1
}
#---------------------------------------------------------------------------------------
# -
#---------------------------------------------------------------------------------------
#
$dataFile = "BasesBuh.xlsx"
# 1-,
$1Cserver = "nn-1cserver"
# 1 , 1.
$ShareName = "1cshare"
#OU Active Directory, 1c
$OU = “OU=1C,OU=Resources,DC=domain,DC=ru”
# DFS , 1
#, , , .
$1CConfigFolder = "\\domain.ru\DfsShare\1cconfig\"
#
#
$strSheetName = 'Sheet1$' # 1$
#----------------------------------------------------------
#
#----------------------------------------------------------
$dataFilePath = $localPath + "\$dataFile"
$localPath = $PSScriptRoot
# 1
$1CBasesCFG = $1CConfigFolder + “1CEStart.cfg”
#
# ACL .
$GRRS_1C_ConfigBasesRO = "GRRS_1C_ConfigBasesRO"
#
# ACL .
$GRRS_1CBases = "GRRS_1CBases"
# 1
$GR_1CAdmins = "GRUS_1Cadmins"
#
If (!(Test-Path -Path $dataFilePath -PathType Any))
{
Write-Host "[ERROR]`t $dataFile ! , $dataFile !" -ForegroundColor Red
Exit 1
}
# Excel- , SQLDB
# Microsoft Access Database Engine 2010 Redistributable
# www.microsoft.com/en-us/download/details.aspx?id=13255
# , . Office
# . , .
$strProvider = "Provider=microsoft.ace.oledb.12.0"
$strDataSource = "Data Source = $dataFilePath"
$strExtend = "Extended Properties=Excel 8.0"
$strQuery = "Select * from [$strSheetName]"
$objConn = New-Object System.Data.OleDb.OleDbConnection("$strProvider;$strDataSource;$strExtend")
$sqlCommand = New-Object System.Data.OleDb.OleDbCommand($strQuery)
$sqlCommand.Connection = $objConn
$objConn.open()
$DataReader = $sqlCommand.ExecuteReader()
#
$AccessArr = New-Object System.Collections.ArrayList
#
While($DataReader.Read())
{
# (.replace(' ','')), - .
$BaseName = $DataReader[2].Tostring().replace(' ','')
$FolderName = $DataReader[3].Tostring().replace(' ','')
$GroupName = $DataReader[4].Tostring().replace(' ','')
# $AccessArr
[void] $AccessArr.Add($DataReader[5].Tostring().replace(' ',''))
[void] $AccessArr.Add($DataReader[6].Tostring().replace(' ',''))
[void] $AccessArr.Add($DataReader[7].Tostring().replace(' ',''))
[void] $AccessArr.Add($DataReader[8].Tostring().replace(' ',''))
[void] $AccessArr.Add($DataReader[8].Tostring().replace(' ',''))
[void] $AccessArr.Add($DataReader[10].Tostring().replace(' ',''))
[void] $AccessArr.Add($DataReader[11].Tostring().replace(' ',''))
# . , .
# . .
$FullPathBase = "\" + "\" + $1Cserver + "\" + $Sharename + "\" + $FolderName
# AD
$CommentBase = “” + “ ” + $BaseName + “ ”
$CommentPath = $FullPathBase
$Comment = $CommentBase + $CommentPath
# ,
$ConfigBaseFile = $1cConfigFolder + $FolderName + “.v8i”
# v8i
# 1, Connect=File
$ConfigBaseFileContent ="[$BaseName]
Connect=File=$FullPathBase
ClientConnectionSpeed=Normal
App=Auto
WA=1
Version=8.3
"
# v8i- 1CEStart.cfg
# v8i-
$ConfigBaseFileContent | Set-Content $ConfigBaseFile -Encoding UTF8
# v8i- 1CEStart.cfg
$1CBasesCFGContent = "CommonInfoBases=$ConfigBaseFile"
# v8i- 1CEStart.cfg
$1CBasesCFGContent | Add-Content $1CBasesCFG -Encoding UTF8
# , .
New-ADGroup -GroupScope DomainLocal -GroupCategory Security `
-name $GroupName -Path $OU -Description $CommentPath -OtherAttributes @{info="$Comment"}
#
Add-ADGroupMember -Identity $GRRS_1C_ConfigBasesRO $GroupName
#
Add-ADGroupMember -Identity $GRRS_1CBases $GroupName
# .
foreach ($i in $AccessArr)
{
if ($i)
{
Add-ADGroupMember -Identity $GroupName $i
}
}
#
New-item -Path $FullPathBase -ItemType directory
#
$acl = Get-Acl $FullPathBase
$GroupOwner = New-Object System.Security.Principal.NTAccount("Builtin", "Administrators")
$acl.SetOwner($GroupOwner)
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule(“Administrators”,”Modify,FullControl, Synchronize”, “ContainerInherit, ObjectInherit”, “None”, “Allow”)
$acl.AddAccessRule($rule)
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule(“Domain admins”,”Modify,FullControl, Synchronize”, “ContainerInherit, ObjectInherit”, “None”, “Allow”)
$acl.AddAccessRule($rule)
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule(“$GroupName”,”Modify, Synchronize”, “ContainerInherit, ObjectInherit”, “None”, “Allow”)
$acl.AddAccessRule($rule)
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule(“$GR_1CAdmins”,”Modify, Synchronize”, “ContainerInherit, ObjectInherit”, “None”, “Allow”)
$acl.AddAccessRule($rule)
$acl.SetAccessRuleProtection($True, $False)
Set-Acl $FullPathBase $acl
# v8i-
$aclfl = Get-Acl $ConfigBaseFile
$GroupOwner = New-Object System.Security.Principal.NTAccount("Builtin", "Administrators")
$aclfl.SetOwner($GroupOwner)
$rulefl = New-Object System.Security.AccessControl.FileSystemAccessRule(“Administrators”,”Modify,FullControl, Synchronize”, “Allow”)
$aclfl.AddAccessRule($rulefl)
$rulefl = New-Object System.Security.AccessControl.FileSystemAccessRule(“Domain admins”,”Modify,FullControl, Synchronize”, “Allow”)
$aclfl.AddAccessRule($rulefl)
$rulefl = New-Object System.Security.AccessControl.FileSystemAccessRule(“$GroupName”,”ReadAndExecute, Synchronize”, “Allow”)
$aclfl.AddAccessRule($rulefl)
$rulefl = New-Object System.Security.AccessControl.FileSystemAccessRule(“$GR_1CAdmins”,”ReadAndExecute, Synchronize”, “Allow”)
$aclfl.AddAccessRule($rulefl)
Set-Acl $ConfigBaseFile $aclfl
# 1CEStart.cfg
$aclcf = Get-Acl $1CBasesCFG
$GroupOwner = New-Object System.Security.Principal.NTAccount("Builtin", "Administrators")
$aclcf.SetOwner($GroupOwner)
$rulecf = New-Object System.Security.AccessControl.FileSystemAccessRule(“Administrators”,”Modify,FullControl, Synchronize”, “Allow”)
$aclcf.AddAccessRule($rulecf)
$rulecf = New-Object System.Security.AccessControl.FileSystemAccessRule(“Domain admins”,”Modify,FullControl, Synchronize”, “Allow”)
$aclcf.AddAccessRule($rulecf)
$rulecf = New-Object System.Security.AccessControl.FileSystemAccessRule(“$GRRS_1C_ConfigBasesRO”,”ReadAndExecute, Synchronize”, “Allow”)
$aclcf.AddAccessRule($rulecf)
$rulecf = New-Object System.Security.AccessControl.FileSystemAccessRule(“$GR_1CAdmins”,”ReadAndExecute, Synchronize”, “Allow”)
$aclcf.AddAccessRule($rulecf)
Set-Acl $1CBasesCFG $aclcf
}
#
$dataReader.close()
$objConn.close()
Possible difficulties
I did not understand for what reasons, but for some reason I didn’t
turn on the “replace all object object permissions with this object” option for some folders with databases, although everything is written in the script. And therefore, after copying the databases to a new location, check whether the rights to the copied files were inherited from the parent folder.
Conclusion
Colleagues, the script is pretty well documented, but written on the knee, in about an hour. All responsibility for its use lies only with the UFO.
I (think) know how to write functions in PowerShell correctly, make requests and check parameters, implement logging, write help for a script, and so on, but I think this is all unnecessary for this script. Although, some checks, for example, directories with configs or shared folders can be done. But, I think, not this time, not such a level is a task.
#ChangeLog- Corrected the inaccuracies pointed out by Sergey-S-Kovalev ;
- Changed the way users are added to the array, n1nj4p0w3r ;
- Added check for Active Directory modules;
- Added a check for the presence of a file with data in the directory.
Thank!
All good!